Compare commits

...

3 Commits

7 changed files with 1279 additions and 286 deletions

View File

@ -1,6 +1,7 @@
import { spawn, exec, ChildProcess } from 'child_process';
import { promisify } from 'util';
import fetch from 'node-fetch';
import * as fs from 'fs';
const execAsync = promisify(exec);
@ -166,7 +167,7 @@ async function stopServer(): Promise<void> {
}
});
// 设置超时,如果 5 秒内没有退出则强制终止
// 设置超时,如果 3 秒内没有退出则强制终止
const timeoutPromise = new Promise<void>((resolve) => {
setTimeout(() => {
if (serverProcess && !serverProcess.killed && serverProcess.exitCode === null) {
@ -174,7 +175,7 @@ async function stopServer(): Promise<void> {
serverProcess.kill('SIGKILL');
}
resolve();
}, 5000);
}, 3000); // 减少超时时间到3秒
});
await Promise.race([exitPromise, timeoutPromise]);
@ -184,22 +185,8 @@ async function stopServer(): Promise<void> {
} finally {
serverProcess = null;
// 额外清理:确保没有遗留的 dotnet 进程
try {
if (process.platform === 'win32') {
// Windows: 使用 taskkill 清理进程
await execAsync('taskkill /F /IM dotnet.exe').catch(() => {
// 忽略错误,可能没有匹配的进程
});
} else {
// 只清理与我们项目相关的进程
await execAsync('pkill -f "dotnet.*run.*--property:Configuration=Release"').catch(() => {
// 忽略错误,可能没有匹配的进程
});
}
} catch (cleanupError) {
// 忽略清理错误
}
// 只有在进程可能没有正常退出时才执行清理
// 移除自动清理逻辑,因为正常退出时不需要
}
}
@ -238,7 +225,7 @@ async function stopWeb(): Promise<void> {
}
});
// 设置超时,如果 5 秒内没有退出则强制终止
// 设置超时,如果 3 秒内没有退出则强制终止
const timeoutPromise = new Promise<void>((resolve) => {
setTimeout(() => {
if (webProcess && !webProcess.killed && webProcess.exitCode === null) {
@ -246,7 +233,7 @@ async function stopWeb(): Promise<void> {
webProcess.kill('SIGKILL');
}
resolve();
}, 5000);
}, 3000); // 减少超时时间到3秒
});
await Promise.race([exitPromise, timeoutPromise]);
@ -256,22 +243,36 @@ async function stopWeb(): Promise<void> {
} finally {
webProcess = null;
// 额外清理:确保没有遗留的 npm/node 进程
try {
if (process.platform === 'win32') {
// Windows: 清理可能的 node 进程
await execAsync('taskkill /F /IM node.exe').catch(() => {
// 忽略错误,可能没有匹配的进程
});
} else {
// 清理可能的 vite 进程
await execAsync('pkill -f "vite"').catch(() => {
// 忽略错误,可能没有匹配的进程
});
}
} catch (cleanupError) {
// 忽略清理错误
// 只有在进程可能没有正常退出时才执行清理
// 移除自动清理逻辑,因为正常退出时不需要
}
}
async function postProcessApiClient(): Promise<void> {
console.log('Post-processing API client...');
try {
const filePath = 'src/APIClient.ts';
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
throw new Error(`API client file not found: ${filePath}`);
}
// 读取文件内容
let content = fs.readFileSync(filePath, 'utf8');
// 替换 ArgumentException 中的 message 属性声明
content = content.replace(
/(\s+)message!:\s*string;/g,
'$1declare message: string;'
);
// 写回文件
fs.writeFileSync(filePath, content, 'utf8');
console.log('✓ API client post-processing completed');
} catch (error) {
throw new Error(`Failed to post-process API client: ${error}`);
}
}
@ -281,6 +282,9 @@ async function generateApiClient(): Promise<void> {
const npxCommand = getCommand('npx');
await execAsync(`${npxCommand} nswag openapi2tsclient /input:http://localhost:5000/swagger/v1/swagger.json /output:src/APIClient.ts`);
console.log('✓ API client generated successfully');
// 添加后处理步骤
await postProcessApiClient();
} catch (error) {
throw new Error(`Failed to generate API client: ${error}`);
}
@ -323,11 +327,28 @@ async function main(): Promise<void> {
}
}
// 改进的进程终止处理
// 改进的进程终止处理 - 添加防重复执行
let isCleaningUp = false;
const cleanup = async (signal: string) => {
if (isCleaningUp) {
console.log('Cleanup already in progress, ignoring signal');
return;
}
isCleaningUp = true;
console.log(`\nReceived ${signal}, cleaning up...`);
await stopServer();
await stopWeb();
try {
await Promise.all([
stopServer(),
stopWeb()
]);
} catch (error) {
console.error('Error during cleanup:', error);
}
// 立即退出,不等待
process.exit(0);
};
@ -336,22 +357,55 @@ process.on('SIGTERM', () => cleanup('SIGTERM'));
// 处理未捕获的异常
process.on('uncaughtException', async (error) => {
if (isCleaningUp) return;
console.error('❌ Uncaught exception:', error);
await stopServer();
await stopWeb();
isCleaningUp = true;
try {
await Promise.all([
stopServer(),
stopWeb()
]);
} catch (cleanupError) {
console.error('Error during cleanup:', cleanupError);
}
process.exit(1);
});
process.on('unhandledRejection', async (reason, promise) => {
if (isCleaningUp) return;
console.error('❌ Unhandled rejection at:', promise, 'reason:', reason);
await stopServer();
await stopWeb();
isCleaningUp = true;
try {
await Promise.all([
stopServer(),
stopWeb()
]);
} catch (cleanupError) {
console.error('Error during cleanup:', cleanupError);
}
process.exit(1);
});
main().catch(async (error) => {
if (isCleaningUp) return;
console.error('❌ Unhandled error:', error);
await stopServer();
await stopWeb();
isCleaningUp = true;
try {
await Promise.all([
stopServer(),
stopWeb()
]);
} catch (cleanupError) {
console.error('Error during cleanup:', cleanupError);
}
process.exit(1);
});

View File

@ -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)

View File

@ -16,11 +16,208 @@ 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>
/// <param name="boardIp">板卡IP地址</param>
/// <param name="boardPort">板卡端口</param>
/// <param name="hostIp">主机IP地址</param>
/// <returns>操作结果</returns>
[HttpPost("SetHostIP")]
@ -28,27 +225,18 @@ public class NetConfigController : ControllerBase
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> SetHostIP(string boardIp, int boardPort, string hostIp)
public async Task<IActionResult> SetHostIP(string hostIp)
{
if (string.IsNullOrWhiteSpace(boardIp))
return BadRequest("板卡IP地址不能为空");
if (boardPort <= 0 || boardPort > 65535)
return BadRequest("板卡端口号无效");
if (string.IsNullOrWhiteSpace(hostIp))
return BadRequest("主机IP地址不能为空");
if (!IPAddress.TryParse(boardIp, out _))
return BadRequest("板卡IP地址格式不正确");
if (!IPAddress.TryParse(hostIp, out var hostIpAddress))
return BadRequest("主机IP地址格式不正确");
try
{
// 创建网络配置客户端
var netConfig = new NetConfig(boardIp, boardPort, 0);
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetHostIP(hostIpAddress);
if (!result.IsSuccessful)
@ -69,8 +257,6 @@ public class NetConfigController : ControllerBase
/// <summary>
/// 设置板卡IP地址
/// </summary>
/// <param name="currentBoardIp">当前板卡IP地址</param>
/// <param name="boardPort">板卡端口</param>
/// <param name="newBoardIp">新的板卡IP地址</param>
/// <returns>操作结果</returns>
[HttpPost("SetBoardIP")]
@ -78,27 +264,18 @@ public class NetConfigController : ControllerBase
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> SetBoardIP(string currentBoardIp, int boardPort, string newBoardIp)
public async Task<IActionResult> SetBoardIP(string newBoardIp)
{
if (string.IsNullOrWhiteSpace(currentBoardIp))
return BadRequest("当前板卡IP地址不能为空");
if (boardPort <= 0 || boardPort > 65535)
return BadRequest("板卡端口号无效");
if (string.IsNullOrWhiteSpace(newBoardIp))
return BadRequest("新的板卡IP地址不能为空");
if (!IPAddress.TryParse(currentBoardIp, out _))
return BadRequest("当前板卡IP地址格式不正确");
if (!IPAddress.TryParse(newBoardIp, out var newIpAddress))
return BadRequest("新的板卡IP地址格式不正确");
try
{
// 创建网络配置客户端
var netConfig = new NetConfig(currentBoardIp, boardPort, 0);
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetBoardIP(newIpAddress);
if (!result.IsSuccessful)
@ -119,8 +296,6 @@ public class NetConfigController : ControllerBase
/// <summary>
/// 设置主机MAC地址
/// </summary>
/// <param name="boardIp">板卡IP地址</param>
/// <param name="boardPort">板卡端口</param>
/// <param name="hostMac">主机MAC地址格式AA:BB:CC:DD:EE:FF</param>
/// <returns>操作结果</returns>
[HttpPost("SetHostMAC")]
@ -128,20 +303,11 @@ public class NetConfigController : ControllerBase
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> SetHostMAC(string boardIp, int boardPort, string hostMac)
public async Task<IActionResult> SetHostMAC(string hostMac)
{
if (string.IsNullOrWhiteSpace(boardIp))
return BadRequest("板卡IP地址不能为空");
if (boardPort <= 0 || boardPort > 65535)
return BadRequest("板卡端口号无效");
if (string.IsNullOrWhiteSpace(hostMac))
return BadRequest("主机MAC地址不能为空");
if (!IPAddress.TryParse(boardIp, out _))
return BadRequest("板卡IP地址格式不正确");
// 解析MAC地址
if (!TryParseMacAddress(hostMac, out var macBytes))
return BadRequest("MAC地址格式不正确请使用格式AA:BB:CC:DD:EE:FF");
@ -149,7 +315,7 @@ public class NetConfigController : ControllerBase
try
{
// 创建网络配置客户端
var netConfig = new NetConfig(boardIp, boardPort, 0);
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetHostMAC(macBytes);
if (!result.IsSuccessful)
@ -167,28 +333,60 @@ 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>
/// <param name="boardIp">板卡IP地址</param>
/// <param name="boardPort">板卡端口</param>
/// <returns>操作结果</returns>
[HttpPost("UpdateHostMAC")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateHostMAC(string boardIp, int boardPort)
public async Task<IActionResult> UpdateHostMAC()
{
if (string.IsNullOrWhiteSpace(boardIp))
return BadRequest("板卡IP地址不能为空");
if (boardPort <= 0 || boardPort > 65535)
return BadRequest("板卡端口号无效");
if (!IPAddress.TryParse(boardIp, out _))
return BadRequest("板卡IP地址格式不正确");
byte[]? macBytes = null;
try
{
@ -204,7 +402,7 @@ public class NetConfigController : ControllerBase
return StatusCode(StatusCodes.Status500InternalServerError, "无法获取本机MAC地址");
// 创建网络配置客户端
var netConfig = new NetConfig(boardIp, boardPort, 0);
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetHostMAC(macBytes);
if (!result.IsSuccessful)
@ -225,8 +423,6 @@ public class NetConfigController : ControllerBase
/// <summary>
/// 设置板卡MAC地址
/// </summary>
/// <param name="boardIp">板卡IP地址</param>
/// <param name="boardPort">板卡端口</param>
/// <param name="boardMac">板卡MAC地址格式AA:BB:CC:DD:EE:FF</param>
/// <returns>操作结果</returns>
[HttpPost("SetBoardMAC")]
@ -234,20 +430,11 @@ public class NetConfigController : ControllerBase
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> SetBoardMAC(string boardIp, int boardPort, string boardMac)
public async Task<IActionResult> SetBoardMAC(string boardMac)
{
if (string.IsNullOrWhiteSpace(boardIp))
return BadRequest("板卡IP地址不能为空");
if (boardPort <= 0 || boardPort > 65535)
return BadRequest("板卡端口号无效");
if (string.IsNullOrWhiteSpace(boardMac))
return BadRequest("板卡MAC地址不能为空");
if (!IPAddress.TryParse(boardIp, out _))
return BadRequest("板卡IP地址格式不正确");
// 解析MAC地址
if (!TryParseMacAddress(boardMac, out var macBytes))
return BadRequest("MAC地址格式不正确请使用格式AA:BB:CC:DD:EE:FF");
@ -255,7 +442,7 @@ public class NetConfigController : ControllerBase
try
{
// 创建网络配置客户端
var netConfig = new NetConfig(boardIp, boardPort, 0);
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetBoardMAC(macBytes);
if (!result.IsSuccessful)
@ -313,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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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,18 +2679,276 @@ 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 boardId (optional) ID
* @param hostIp (optional) IP地址
* @return
*/
setHostIP(boardId: string | undefined, hostIp: string | undefined): Promise<boolean> {
setHostIP(hostIp: string | undefined): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/SetHostIP?";
if (boardId === null)
throw new Error("The parameter 'boardId' cannot be null.");
else if (boardId !== undefined)
url_ += "boardId=" + encodeURIComponent("" + boardId) + "&";
if (hostIp === null)
throw new Error("The parameter 'hostIp' cannot be null.");
else if (hostIp !== undefined)
@ -2737,13 +2985,6 @@ export class NetConfigClient {
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 404) {
return response.text().then((_responseText) => {
let result404: any = null;
let resultData404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result404 = ProblemDetails.fromJS(resultData404);
return throwException("A server side error occurred.", status, _responseText, _headers, result404);
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
@ -2758,20 +2999,15 @@ export class NetConfigClient {
/**
* IP地址
* @param boardId (optional) ID
* @param boardIp (optional) IP地址
* @param newBoardIp (optional) IP地址
* @return
*/
setBoardIP(boardId: string | undefined, boardIp: string | undefined): Promise<boolean> {
setBoardIP(newBoardIp: string | undefined): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/SetBoardIP?";
if (boardId === null)
throw new Error("The parameter 'boardId' cannot be null.");
else if (boardId !== undefined)
url_ += "boardId=" + encodeURIComponent("" + boardId) + "&";
if (boardIp === null)
throw new Error("The parameter 'boardIp' cannot be null.");
else if (boardIp !== undefined)
url_ += "boardIp=" + encodeURIComponent("" + boardIp) + "&";
if (newBoardIp === null)
throw new Error("The parameter 'newBoardIp' cannot be null.");
else if (newBoardIp !== undefined)
url_ += "newBoardIp=" + encodeURIComponent("" + newBoardIp) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
@ -2804,13 +3040,6 @@ export class NetConfigClient {
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 404) {
return response.text().then((_responseText) => {
let result404: any = null;
let resultData404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result404 = ProblemDetails.fromJS(resultData404);
return throwException("A server side error occurred.", status, _responseText, _headers, result404);
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
@ -2825,16 +3054,11 @@ export class NetConfigClient {
/**
* MAC地址
* @param boardId (optional) ID
* @param hostMac (optional) MAC地址AA:BB:CC:DD:EE:FF
* @return
*/
setHostMAC(boardId: string | undefined, hostMac: string | undefined): Promise<boolean> {
setHostMAC(hostMac: string | undefined): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/SetHostMAC?";
if (boardId === null)
throw new Error("The parameter 'boardId' cannot be null.");
else if (boardId !== undefined)
url_ += "boardId=" + encodeURIComponent("" + boardId) + "&";
if (hostMac === null)
throw new Error("The parameter 'hostMac' cannot be null.");
else if (hostMac !== undefined)
@ -2871,12 +3095,48 @@ export class NetConfigClient {
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 404) {
} else if (status === 500) {
return response.text().then((_responseText) => {
let result404: any = null;
let resultData404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result404 = ProblemDetails.fromJS(resultData404);
return throwException("A server side error occurred.", status, _responseText, _headers, result404);
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);
}
/**
* 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) => {
@ -2892,15 +3152,10 @@ export class NetConfigClient {
/**
* MAC地址
* @param boardId (optional) ID
* @return
*/
updateHostMAC(boardId: string | undefined): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/UpdateHostMAC?";
if (boardId === null)
throw new Error("The parameter 'boardId' cannot be null.");
else if (boardId !== undefined)
url_ += "boardId=" + encodeURIComponent("" + boardId) + "&";
updateHostMAC(): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/UpdateHostMAC";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
@ -2933,13 +3188,6 @@ export class NetConfigClient {
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 404) {
return response.text().then((_responseText) => {
let result404: any = null;
let resultData404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result404 = ProblemDetails.fromJS(resultData404);
return throwException("A server side error occurred.", status, _responseText, _headers, result404);
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
@ -2954,16 +3202,11 @@ export class NetConfigClient {
/**
* MAC地址
* @param boardId (optional) ID
* @param boardMac (optional) MAC地址AA:BB:CC:DD:EE:FF
* @return
*/
setBoardMAC(boardId: string | undefined, boardMac: string | undefined): Promise<boolean> {
setBoardMAC(boardMac: string | undefined): Promise<boolean> {
let url_ = this.baseUrl + "/api/NetConfig/SetBoardMAC?";
if (boardId === null)
throw new Error("The parameter 'boardId' cannot be null.");
else if (boardId !== undefined)
url_ += "boardId=" + encodeURIComponent("" + boardId) + "&";
if (boardMac === null)
throw new Error("The parameter 'boardMac' cannot be null.");
else if (boardMac !== undefined)
@ -3000,13 +3243,6 @@ export class NetConfigClient {
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 404) {
return response.text().then((_responseText) => {
let result404: any = null;
let resultData404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result404 = ProblemDetails.fromJS(resultData404);
return throwException("A server side error occurred.", status, _responseText, _headers, result404);
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
@ -3799,7 +4035,7 @@ export class UDPClient {
}
export class Exception implements IException {
message!: string;
declare message: string;
innerException?: Exception | undefined;
source?: string | undefined;
stackTrace?: string | undefined;
@ -4093,6 +4329,8 @@ export class Board implements IBoard {
boardName!: string;
/** FPGA 板子的IP地址 */
ipAddr!: string;
/** FPGA 板子的MAC地址 */
macAddr!: string;
/** FPGA 板子的通信端口 */
port!: number;
/** FPGA 板子的当前状态 */
@ -4118,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"];
@ -4138,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;
@ -4155,6 +4395,8 @@ export interface IBoard {
boardName: string;
/** FPGA 板子的IP地址 */
ipAddr: string;
/** FPGA 板子的MAC地址 */
macAddr: string;
/** FPGA 板子的通信端口 */
port: number;
/** FPGA 板子的当前状态 */
@ -4169,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 {
@ -4385,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 {
/** 突发类型 */