Browse Source

Update network configuration and refactor network services

master
root 6 days ago
parent
commit
3de14aee8b
  1. 4
      CoreAgent.API/Configurations/NetworkConfig.json
  2. 160
      CoreAgent.API/Configurations/netcommand.json
  3. 4
      CoreAgent.API/Controllers/CellularNetworkController.cs
  4. 87
      CoreAgent.API/Controllers/NetworkConfigController.cs
  5. 67
      CoreAgent.API/logs/log-20250611.txt
  6. 5
      CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs
  7. 42
      CoreAgent.Application/Commands/NetworkConfig/CreateNetworkConfigurationCommand.cs
  8. 15
      CoreAgent.Application/Commands/NetworkConfig/DeleteNetworkConfigurationCommand.cs
  9. 10
      CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs
  10. 2
      CoreAgent.Application/Handlers/CellularNetwork/StopCellularNetworkCommandHandler.cs
  11. 81
      CoreAgent.Application/Handlers/NetworkConfig/Commands/CreateNetworkConfigurationCommandHandler.cs
  12. 38
      CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs
  13. 66
      CoreAgent.Application/Handlers/NetworkConfig/Queries/GetNetworkConfigurationQueryHandler.cs
  14. 55
      CoreAgent.Application/Interfaces/INetworkConfigurationService.cs
  15. 24
      CoreAgent.Application/Queries/NetworkConfig/GetNetworkConfigurationQuery.cs
  16. 80
      CoreAgent.Domain/Contexts/CellularNetworkContext.cs
  17. 100
      CoreAgent.Domain/Entities/NetworkConfiguration.cs
  18. 55
      CoreAgent.Domain/Interfaces/INetworkConfigurationRepository.cs
  19. 55
      CoreAgent.Domain/Interfaces/INetworkConfigurationService.cs
  20. 25
      CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs
  21. 25
      CoreAgent.Domain/Interfaces/Network/INetworkConfigurator.cs
  22. 36
      CoreAgent.Domain/Interfaces/Network/INetworkStatusProvider.cs
  23. 24
      CoreAgent.Domain/Models/System/CommandTemplateConfig.cs
  24. 11
      CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
  25. 175
      CoreAgent.Infrastructure/Repositories/NetworkConfigurationRepository.cs
  26. 110
      CoreAgent.Infrastructure/Services/Network/CellularNetworkConfigurator.cs
  27. 349
      CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs
  28. 244
      CoreAgent.Infrastructure/Services/Network/CellularNetworkStatusProvider.cs
  29. 13
      CoreAgent.Infrastructure/Services/Network/Extensions/ServiceCollectionExtensions.cs
  30. 70
      CoreAgent.Infrastructure/Services/NetworkConfigurationService.cs

4
CoreAgent.API/Configurations/NetworkConfig.json

@ -1,4 +1,6 @@
{ {
"networkConfigurations": [
{
"configKey": "Default", "configKey": "Default",
"ragConfig": "Config/Ran/default.cfg", "ragConfig": "Config/Ran/default.cfg",
"coreOrImsConfigs": [ "coreOrImsConfigs": [
@ -23,4 +25,6 @@
"B8" "B8"
], ],
"comment": "默认网络配置" "comment": "默认网络配置"
}
]
} }

160
CoreAgent.API/Configurations/netcommand.json

@ -4,58 +4,154 @@
"DefaultRetryInterval": 1000, "DefaultRetryInterval": 1000,
"NetworkCommands": [ "NetworkCommands": [
{ {
"type": 1, "type": 0,
"template": "network init", "template": "lte",
"timeout": 30000, "timeout": 5000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": true,
"hasParameters": false
}, },
{ {
"type": 1, "type": 0,
"template": "network check", "template": "ntp",
"timeout": 5000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": true,
"hasParameters": false
},
{
"type": 0,
"template": "ping",
"timeout": 5000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": true,
"hasParameters": false
},
{
"type": 0,
"template": "tcpdump",
"timeout": 5000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": true,
"hasParameters": false
},
{
"type": 0,
"template": "chmod 777 /etc/shscripts/ntp.sh",
"timeout": 5000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
},
{
"type": 0,
"template": "nohup sh /etc/shscripts/ntp.sh >/tmp/ntp.log 2>&1 &",
"timeout": 15000, "timeout": 15000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 1, "type": 0,
"template": "network verify", "template": "chmod 777 /root/enb/lte_init.sh",
"timeout": 20000, "timeout": 5000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 2, "type": 0,
"template": "network start", "template": "chmod 777 /root/mme/lte_init.sh",
"timeout": 25000, "timeout": 5000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 2, "type": 0,
"template": "network resume", "template": "sh /root/enb/lte_init.sh",
"timeout": 20000, "timeout": 20000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 3, "type": 0,
"template": "network stop", "template": "sh /root/mme/lte_init.sh",
"timeout": 8000, "timeout": 20000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 3, "type": 0,
"template": "network cleanup", "template": "rm -f /tmp/*",
"timeout": 5000, "timeout": 5000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 4, "type": 0,
"template": "network status", "template": "rm -f /var/log/lte/*",
"timeout": 5000, "timeout": 5000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
}, },
{ {
"type": 4, "type": 0,
"template": "network info", "template": "killall screen",
"timeout": 5000, "timeout": 2000,
"isEnabled": true "isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
},
{
"type": 0,
"template": "rm -f /tmp/*.log",
"timeout": 2000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": false
},
{
"type": 1,
"template": "sudo sh /etc/shscripts/network_se_{0}.sh",
"timeout": 15000,
"isEnabled": true,
"needReturnResult": false,
"needBackgroundExecution": false,
"canBeKilled": false,
"hasParameters": true
} }
] ]
} }

4
CoreAgent.API/Controllers/CellularNetworkController.cs

@ -8,9 +8,7 @@ namespace CoreAgent.API.Controllers;
/// <summary> /// <summary>
/// 蜂窝网络控制器 /// 蜂窝网络控制器
/// </summary> /// </summary>
[ApiController]
[ApiVersion("1.0")] [ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class CellularNetworkController : BaseApiController public class CellularNetworkController : BaseApiController
{ {
private readonly ILogger<CellularNetworkController> _logger; private readonly ILogger<CellularNetworkController> _logger;
@ -30,7 +28,7 @@ public class CellularNetworkController : BaseApiController
[HttpPost("start")] [HttpPost("start")]
public async Task<IActionResult> Start([FromBody] StartCellularNetworkCommand command) public async Task<IActionResult> Start([FromBody] StartCellularNetworkCommand command)
{ {
_logger.LogInformation("收到启动蜂窝网络请求: {InterfaceName}", command.InterfaceName); _logger.LogInformation("收到启动蜂窝网络请求: {InterfaceName}", command.Key);
return await HandleRequest<StartCellularNetworkCommand, bool>(command); return await HandleRequest<StartCellularNetworkCommand, bool>(command);
} }

87
CoreAgent.API/Controllers/NetworkConfigController.cs

@ -0,0 +1,87 @@
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
using CoreAgent.Application.Queries.NetworkConfig;
using CoreAgent.Domain.Entities;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace CoreAgent.API.Controllers
{
/// <summary>
/// 网络配置控制器
/// </summary>
[ApiVersion("1.0")]
public class NetworkConfigController : BaseApiController
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="mediator">中介者</param>
/// <param name="logger">日志记录器</param>
public NetworkConfigController(IMediator mediator, ILogger<NetworkConfigController> logger)
: base(mediator, logger)
{
}
/// <summary>
/// 获取所有网络配置
/// </summary>
/// <returns>网络配置列表</returns>
[HttpGet]
[ProducesResponseType(typeof(List<NetworkConfiguration>), 200)]
public async Task<IActionResult> GetAll()
{
return await HandleRequest<GetAllNetworkConfigurationsQuery, List<NetworkConfiguration>>(
new GetAllNetworkConfigurationsQuery());
}
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <returns>网络配置</returns>
[HttpGet("{configKey}")]
[ProducesResponseType(typeof(NetworkConfiguration), 200)]
[ProducesResponseType(404)]
public async Task<IActionResult> GetByKey(string configKey)
{
return await HandleRequest<GetNetworkConfigurationByKeyQuery, NetworkConfiguration>(
new GetNetworkConfigurationByKeyQuery { ConfigKey = configKey });
}
/// <summary>
/// 创建网络配置
/// </summary>
/// <param name="command">创建网络配置命令</param>
/// <returns>创建的网络配置</returns>
[HttpPost]
[ProducesResponseType(typeof(NetworkConfiguration), 201)]
[ProducesResponseType(400)]
public async Task<IActionResult> Create([FromBody] CreateNetworkConfigurationCommand command)
{
var result = await HandleRequest<CreateNetworkConfigurationCommand, NetworkConfiguration>(command);
if (result is OkObjectResult okResult)
{
return CreatedAtAction(nameof(GetByKey),
new { configKey = command.ConfigKey },
okResult.Value);
}
return result;
}
/// <summary>
/// 删除网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <returns>操作结果</returns>
[HttpDelete("{configKey}")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public async Task<IActionResult> Delete(string configKey)
{
var command = new DeleteNetworkConfigurationCommand { ConfigKey = configKey };
return await HandleRequest<DeleteNetworkConfigurationCommand, Unit>(command);
}
}
}

67
CoreAgent.API/logs/log-20250611.txt

@ -384,3 +384,70 @@ System.Exception: 命令执行失败:
2025-06-11 17:35:49.102 +08:00 [INF] Handling request of type StartCellularNetworkCommand 2025-06-11 17:35:49.102 +08:00 [INF] Handling request of type StartCellularNetworkCommand
2025-06-11 17:35:49.108 +08:00 [INF] 正在启动蜂窝网络接口: string 2025-06-11 17:35:49.108 +08:00 [INF] 正在启动蜂窝网络接口: string
2025-06-11 17:36:00.832 +08:00 [INF] 正在启动蜂窝网络接口: string 2025-06-11 17:36:00.832 +08:00 [INF] 正在启动蜂窝网络接口: string
2025-06-11 23:03:09.183 +08:00 [INF] Logger initialized successfully
2025-06-11 23:03:09.207 +08:00 [INF] Application starting...
2025-06-11 23:03:10.909 +08:00 [INF] Application startup completed
2025-06-11 23:03:21.198 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:03:21.236 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:03:21.261 +08:00 [INF] Response for GET /api/v1/NetworkConfig: 200 - {"data":[],"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:03:21.267 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig in 73ms with status code 200
2025-06-11 23:06:56.130 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:06:56.135 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:12:09.338 +08:00 [INF] Logger initialized successfully
2025-06-11 23:12:09.360 +08:00 [INF] Application starting...
2025-06-11 23:12:11.093 +08:00 [INF] Application startup completed
2025-06-11 23:12:17.970 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:12:18.001 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:12:39.226 +08:00 [INF] Logger initialized successfully
2025-06-11 23:12:39.252 +08:00 [INF] Application starting...
2025-06-11 23:12:39.560 +08:00 [INF] Application startup completed
2025-06-11 23:12:43.773 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:12:43.802 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:12:50.443 +08:00 [INF] Response for GET /api/v1/NetworkConfig: 200 - {"data":[],"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:12:50.447 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig in 6677ms with status code 200
2025-06-11 23:12:53.114 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:12:53.118 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:12:56.241 +08:00 [INF] Response for GET /api/v1/NetworkConfig: 200 - {"data":[],"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:12:56.244 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig in 3129ms with status code 200
2025-06-11 23:12:58.245 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:12:58.249 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:14:11.713 +08:00 [INF] Logger initialized successfully
2025-06-11 23:14:11.735 +08:00 [INF] Application starting...
2025-06-11 23:14:11.950 +08:00 [INF] Application startup completed
2025-06-11 23:14:16.729 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:14:16.760 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:15:52.058 +08:00 [INF] Logger initialized successfully
2025-06-11 23:15:52.085 +08:00 [INF] Application starting...
2025-06-11 23:15:52.306 +08:00 [INF] Application startup completed
2025-06-11 23:15:56.713 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:15:56.743 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:27:44.015 +08:00 [INF] Logger initialized successfully
2025-06-11 23:27:44.041 +08:00 [INF] Application starting...
2025-06-11 23:27:44.270 +08:00 [INF] Application startup completed
2025-06-11 23:27:48.801 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:27:48.831 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:27:52.841 +08:00 [INF] Response for GET /api/v1/NetworkConfig: 200 - {"data":[{"configKey":null,"ragConfig":null,"coreOrImsConfigs":[],"apn":null,"band":[],"comment":null}],"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:27:52.847 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig in 4049ms with status code 200
2025-06-11 23:28:03.795 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:28:03.799 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:30:26.955 +08:00 [INF] Logger initialized successfully
2025-06-11 23:30:26.978 +08:00 [INF] Application starting...
2025-06-11 23:30:27.187 +08:00 [INF] Application startup completed
2025-06-11 23:30:34.014 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:30:34.053 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:32:01.737 +08:00 [INF] Logger initialized successfully
2025-06-11 23:32:01.759 +08:00 [INF] Application starting...
2025-06-11 23:32:02.037 +08:00 [INF] Application startup completed
2025-06-11 23:32:08.601 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:32:08.635 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:34:48.328 +08:00 [INF] Logger initialized successfully
2025-06-11 23:34:48.351 +08:00 [INF] Application starting...
2025-06-11 23:34:48.570 +08:00 [INF] Application startup completed
2025-06-11 23:34:52.677 +08:00 [INF] Request started: GET /api/v1/NetworkConfig
2025-06-11 23:34:52.706 +08:00 [INF] Handling request of type GetAllNetworkConfigurationsQuery
2025-06-11 23:35:14.323 +08:00 [INF] Response for GET /api/v1/NetworkConfig: 200 - {"data":[{"configKey":"Default","ragConfig":"Config/Ran/default.cfg","coreOrImsConfigs":[{"index":1,"plmn":"46000","coreNetworkConfig":"Config/CoreNetwork/plmn_46000.cfg","imsConfig":"Config/Ims/plmn_46000.cfg"},{"index":2,"plmn":"46001","coreNetworkConfig":"Config/CoreNetwork/plmn_46001.cfg","imsConfig":"Config/Ims/plmn_46001.cfg"}],"apn":"Internet","band":["B1","B3","B5","B8"],"comment":"默认网络配置"}],"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:35:14.328 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig in 21656ms with status code 200
2025-06-11 23:35:48.286 +08:00 [INF] Request started: GET /api/v1/NetworkConfig/Default
2025-06-11 23:35:48.325 +08:00 [INF] Handling request of type GetNetworkConfigurationByKeyQuery
2025-06-11 23:35:57.061 +08:00 [INF] Response for GET /api/v1/NetworkConfig/Default: 200 - {"data":{"configKey":"Default","ragConfig":"Config/Ran/default.cfg","coreOrImsConfigs":[{"index":1,"plmn":"46000","coreNetworkConfig":"Config/CoreNetwork/plmn_46000.cfg","imsConfig":"Config/Ims/plmn_46000.cfg"},{"index":2,"plmn":"46001","coreNetworkConfig":"Config/CoreNetwork/plmn_46001.cfg","imsConfig":"Config/Ims/plmn_46001.cfg"}],"apn":"Internet","band":["B1","B3","B5","B8"],"comment":"默认网络配置"},"isSuccess":true,"message":"操作成功","errorCode":"","statusCode":200}
2025-06-11 23:35:57.063 +08:00 [INF] Request completed: GET /api/v1/NetworkConfig/Default in 8778ms with status code 200

5
CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs

@ -12,9 +12,4 @@ public class StartCellularNetworkCommand : IRequest<bool>
/// 网络接口名称 /// 网络接口名称
/// </summary> /// </summary>
public string Key { get; set; } public string Key { get; set; }
/// <summary>
/// 网络配置
/// </summary>
public CellularNetworkConfig Config { get; set; }
} }

42
CoreAgent.Application/Commands/NetworkConfig/CreateNetworkConfigurationCommand.cs

@ -0,0 +1,42 @@
using System.Collections.Generic;
using CoreAgent.Domain.Entities;
using MediatR;
namespace CoreAgent.Application.Commands.NetworkConfig
{
/// <summary>
/// 创建网络配置命令
/// </summary>
public class CreateNetworkConfigurationCommand : IRequest<NetworkConfiguration>
{
/// <summary>
/// 配置键值
/// </summary>
public string ConfigKey { get; set; }
/// <summary>
/// RAN配置文件路径
/// </summary>
public string RagConfig { get; set; }
/// <summary>
/// 核心网和IMS配置列表
/// </summary>
public List<CoreImsConfig> CoreOrImsConfigs { get; set; }
/// <summary>
/// APN配置
/// </summary>
public string Apn { get; set; }
/// <summary>
/// 频段配置
/// </summary>
public List<string> Band { get; set; }
/// <summary>
/// 配置说明
/// </summary>
public string Comment { get; set; }
}
}

15
CoreAgent.Application/Commands/NetworkConfig/DeleteNetworkConfigurationCommand.cs

@ -0,0 +1,15 @@
using MediatR;
namespace CoreAgent.Application.Commands.NetworkConfig
{
/// <summary>
/// 删除网络配置命令
/// </summary>
public class DeleteNetworkConfigurationCommand : IRequest<Unit>
{
/// <summary>
/// 配置键值
/// </summary>
public string ConfigKey { get; set; }
}
}

10
CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs

@ -25,14 +25,14 @@ public class StartCellularNetworkCommandHandler : IRequestHandler<StartCellularN
{ {
try try
{ {
_logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", request.InterfaceName); _logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", request.Key);
// 启动网络 // 启动网络
var result = await _cellularNetworkService.StartAsync(request.InterfaceName, request.Config); var result = await _cellularNetworkService.StartAsync(request.Key);
if (result) if (result)
{ {
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", request.InterfaceName); _logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", request.Key);
//// 获取全局状态 //// 获取全局状态
//var status = await _cellularNetworkService.GetGlobalStatusAsync(); //var status = await _cellularNetworkService.GetGlobalStatusAsync();
@ -45,14 +45,14 @@ public class StartCellularNetworkCommandHandler : IRequestHandler<StartCellularN
} }
else else
{ {
_logger.LogWarning("蜂窝网络接口 {InterfaceName} 启动失败", request.InterfaceName); _logger.LogWarning("蜂窝网络接口 {InterfaceName} 启动失败", request.Key);
} }
return result; return result;
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "启动蜂窝网络接口 {InterfaceName} 失败", request.InterfaceName); _logger.LogError(ex, "启动蜂窝网络接口 {InterfaceName} 失败", request.Key);
return false; return false;
} }
} }

2
CoreAgent.Application/Handlers/CellularNetwork/StopCellularNetworkCommandHandler.cs

@ -28,7 +28,7 @@ public class StopCellularNetworkCommandHandler : IRequestHandler<StopCellularNet
_logger.LogInformation("正在停止蜂窝网络接口: {InterfaceName}", request.InterfaceName); _logger.LogInformation("正在停止蜂窝网络接口: {InterfaceName}", request.InterfaceName);
// 停止网络 // 停止网络
var result = await _cellularNetworkService.StopAsync(request.InterfaceName); var result = await _cellularNetworkService.StopAsync();
if (result) if (result)
{ {

81
CoreAgent.Application/Handlers/NetworkConfig/Commands/CreateNetworkConfigurationCommandHandler.cs

@ -0,0 +1,81 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
using MediatR;
namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
{
/// <summary>
/// 创建网络配置命令
/// </summary>
public class CreateNetworkConfigurationCommand : IRequest<NetworkConfiguration>
{
/// <summary>
/// 配置键值
/// </summary>
public string ConfigKey { get; set; }
/// <summary>
/// RAN配置文件路径
/// </summary>
public string RagConfig { get; set; }
/// <summary>
/// 核心网和IMS配置列表
/// </summary>
public List<CoreImsConfig> CoreOrImsConfigs { get; set; }
/// <summary>
/// APN配置
/// </summary>
public string Apn { get; set; }
/// <summary>
/// 频段配置
/// </summary>
public List<string> Band { get; set; }
/// <summary>
/// 配置说明
/// </summary>
public string Comment { get; set; }
}
/// <summary>
/// 创建网络配置命令处理器
/// </summary>
public class CreateNetworkConfigurationCommandHandler : IRequestHandler<CreateNetworkConfigurationCommand, NetworkConfiguration>
{
private readonly INetworkConfigurationService _service;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service">网络配置服务</param>
public CreateNetworkConfigurationCommandHandler(INetworkConfigurationService service)
{
_service = service;
}
/// <summary>
/// 处理创建网络配置命令
/// </summary>
/// <param name="request">创建网络配置命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>创建的网络配置</returns>
public async Task<NetworkConfiguration> Handle(CreateNetworkConfigurationCommand request, CancellationToken cancellationToken)
{
return await _service.CreateAsync(
request.ConfigKey,
request.RagConfig,
request.CoreOrImsConfigs,
request.Apn,
request.Band,
request.Comment
);
}
}
}

38
CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs

@ -0,0 +1,38 @@
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
using CoreAgent.Domain.Interfaces;
using MediatR;
namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
{
/// <summary>
/// 删除网络配置命令处理器
/// </summary>
public class DeleteNetworkConfigurationCommandHandler : IRequestHandler<DeleteNetworkConfigurationCommand, Unit>
{
private readonly INetworkConfigurationService _service;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service">网络配置服务</param>
public DeleteNetworkConfigurationCommandHandler(INetworkConfigurationService service)
{
_service = service;
}
/// <summary>
/// 处理删除网络配置命令
/// </summary>
/// <param name="request">删除网络配置命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>操作结果</returns>
public async Task<Unit> Handle(DeleteNetworkConfigurationCommand request, CancellationToken cancellationToken)
{
await _service.DeleteAsync(request.ConfigKey);
return Unit.Value;
}
}
}

66
CoreAgent.Application/Handlers/NetworkConfig/Queries/GetNetworkConfigurationQueryHandler.cs

@ -0,0 +1,66 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Queries.NetworkConfig;
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
using MediatR;
namespace CoreAgent.Application.Handlers.NetworkConfig.Queries
{
/// <summary>
/// 获取所有网络配置查询处理器
/// </summary>
public class GetAllNetworkConfigurationsQueryHandler : IRequestHandler<GetAllNetworkConfigurationsQuery, List<NetworkConfiguration>>
{
private readonly INetworkConfigurationService _service;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service">网络配置服务</param>
public GetAllNetworkConfigurationsQueryHandler(INetworkConfigurationService service)
{
_service = service;
}
/// <summary>
/// 处理获取所有网络配置查询
/// </summary>
/// <param name="request">获取所有网络配置查询</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>网络配置列表</returns>
public Task<List<NetworkConfiguration>> Handle(GetAllNetworkConfigurationsQuery request, CancellationToken cancellationToken)
{
return _service.GetAllAsync();
}
}
/// <summary>
/// 根据配置键获取网络配置查询处理器
/// </summary>
public class GetNetworkConfigurationByKeyQueryHandler : IRequestHandler<GetNetworkConfigurationByKeyQuery, NetworkConfiguration>
{
private readonly INetworkConfigurationService _service;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service">网络配置服务</param>
public GetNetworkConfigurationByKeyQueryHandler(INetworkConfigurationService service)
{
_service = service;
}
/// <summary>
/// 处理根据配置键获取网络配置查询
/// </summary>
/// <param name="request">根据配置键获取网络配置查询</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>网络配置</returns>
public Task<NetworkConfiguration> Handle(GetNetworkConfigurationByKeyQuery request, CancellationToken cancellationToken)
{
return _service.GetByConfigKeyAsync(request.ConfigKey);
}
}
}

55
CoreAgent.Application/Interfaces/INetworkConfigurationService.cs

@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CoreAgent.Domain.Entities;
namespace CoreAgent.Application.Interfaces
{
/// <summary>
/// 网络配置服务接口
/// </summary>
public interface INetworkConfigurationService
{
/// <summary>
/// 创建网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <param name="ragConfig">RAN配置文件路径</param>
/// <param name="coreOrImsConfigs">核心网和IMS配置列表</param>
/// <param name="apn">APN配置</param>
/// <param name="band">频段配置</param>
/// <param name="comment">配置说明</param>
/// <returns>创建的网络配置</returns>
Task<NetworkConfiguration> CreateAsync(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null);
/// <summary>
/// 保存网络配置
/// </summary>
/// <param name="configuration">网络配置</param>
Task SaveAsync(NetworkConfiguration configuration);
/// <summary>
/// 删除网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
Task DeleteAsync(string configKey);
/// <summary>
/// 获取所有网络配置
/// </summary>
/// <returns>网络配置列表</returns>
Task<List<NetworkConfiguration>> GetAllAsync();
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <returns>网络配置</returns>
Task<NetworkConfiguration> GetByConfigKeyAsync(string configKey);
}
}

24
CoreAgent.Application/Queries/NetworkConfig/GetNetworkConfigurationQuery.cs

@ -0,0 +1,24 @@
using System.Collections.Generic;
using CoreAgent.Domain.Entities;
using MediatR;
namespace CoreAgent.Application.Queries.NetworkConfig
{
/// <summary>
/// 获取所有网络配置查询
/// </summary>
public class GetAllNetworkConfigurationsQuery : IRequest<List<NetworkConfiguration>>
{
}
/// <summary>
/// 根据配置键获取网络配置查询
/// </summary>
public class GetNetworkConfigurationByKeyQuery : IRequest<NetworkConfiguration>
{
/// <summary>
/// 配置键值
/// </summary>
public string ConfigKey { get; set; }
}
}

80
CoreAgent.Domain/Contexts/CellularNetworkContext.cs

@ -13,7 +13,8 @@ public class CellularNetworkContext
private readonly object _lock = new(); private readonly object _lock = new();
private readonly Dictionary<string, CellularNetworkState> _networkStates = new(); private readonly Dictionary<string, CellularNetworkState> _networkStates = new();
private NetworkCommandConfig _networkCommandConfig; private NetworkCommandConfig _networkCommandConfig;
private string NeConfigKey;
public CancellationTokenSource token =new CancellationTokenSource();
/// <summary> /// <summary>
/// 获取单例实例 /// 获取单例实例
/// </summary> /// </summary>
@ -45,6 +46,21 @@ public class CellularNetworkContext
} }
} }
public string SetNeConfigKey(string key)
{
lock (_lock)
{
return NeConfigKey= key ?? throw new ArgumentNullException(nameof(key));
}
}
public string GetNeConfigKey()
{
lock (_lock)
{
return NeConfigKey;
}
}
/// <summary> /// <summary>
/// 获取指定类型的命令配置 /// 获取指定类型的命令配置
/// </summary> /// </summary>
@ -73,16 +89,16 @@ public class CellularNetworkContext
/// <summary> /// <summary>
/// 获取或创建网络状态 /// 获取或创建网络状态
/// </summary> /// </summary>
/// <param name="interfaceName">网络接口名称</param> /// <param name="NeConfigKey">网络接口名称</param>
/// <returns>网络状态</returns> /// <returns>网络状态</returns>
public CellularNetworkState GetOrCreateNetworkState(string interfaceName) public CellularNetworkState GetOrCreateNetworkState(string NeConfigKey)
{ {
lock (_lock) lock (_lock)
{ {
if (!_networkStates.TryGetValue(interfaceName, out var state)) if (!_networkStates.TryGetValue(NeConfigKey, out var state))
{ {
state = new CellularNetworkState(interfaceName); state = new CellularNetworkState(NeConfigKey);
_networkStates[interfaceName] = state; _networkStates[NeConfigKey] = state;
} }
return state; return state;
} }
@ -91,12 +107,12 @@ public class CellularNetworkContext
/// <summary> /// <summary>
/// 移除网络状态 /// 移除网络状态
/// </summary> /// </summary>
/// <param name="interfaceName">网络接口名称</param> /// <param name="NeConfigKey">网络接口名称</param>
public void RemoveNetworkState(string interfaceName) public void RemoveNetworkState(string NeConfigKey)
{ {
lock (_lock) lock (_lock)
{ {
_networkStates.Remove(interfaceName); _networkStates.Remove(NeConfigKey);
} }
} }
@ -121,7 +137,7 @@ public class CellularNetworkState
/// <summary> /// <summary>
/// 网络接口名称 /// 网络接口名称
/// </summary> /// </summary>
public string InterfaceName { get; } public string NeConfigKey { get; }
/// <summary> /// <summary>
/// 是否已初始化 /// 是否已初始化
@ -143,34 +159,18 @@ public class CellularNetworkState
/// </summary> /// </summary>
public NetworkStatus CurrentStatus { get; private set; } public NetworkStatus CurrentStatus { get; private set; }
/// <summary>
/// 当前信号强度
/// </summary>
public SignalStrength CurrentSignalStrength { get; private set; }
/// <summary> /// <summary>
/// 当前网络类型 /// 当前网络类型
/// </summary> /// </summary>
public NetworkType CurrentNetworkType { get; private set; } public NetworkType CurrentNetworkType { get; private set; }
/// <summary>
/// 当前发射功率
/// </summary>
public int CurrentTransmitPower { get; private set; }
/// <summary>
/// 网络配置
/// </summary>
public CellularNetworkConfig Config { get; private set; }
public CellularNetworkState(string interfaceName) public CellularNetworkState(string _NeConfigKey)
{ {
InterfaceName = interfaceName; NeConfigKey = _NeConfigKey;
IsInitialized = false; IsInitialized = false;
CurrentStatus = NetworkStatus.Unknown; CurrentStatus = NetworkStatus.Unknown;
CurrentSignalStrength = SignalStrength.NoSignal;
CurrentNetworkType = NetworkType.Unknown;
CurrentTransmitPower = 0;
} }
/// <summary> /// <summary>
@ -181,13 +181,6 @@ public class CellularNetworkState
CurrentStatus = status; CurrentStatus = status;
} }
/// <summary>
/// 更新信号强度
/// </summary>
public void UpdateSignalStrength(SignalStrength strength)
{
CurrentSignalStrength = strength;
}
/// <summary> /// <summary>
/// 更新网络类型 /// 更新网络类型
@ -197,21 +190,6 @@ public class CellularNetworkState
CurrentNetworkType = type; CurrentNetworkType = type;
} }
/// <summary>
/// 更新发射功率
/// </summary>
public void UpdateTransmitPower(int power)
{
CurrentTransmitPower = power;
}
/// <summary>
/// 更新网络配置
/// </summary>
public void UpdateConfig(CellularNetworkConfig config)
{
Config = config;
}
/// <summary> /// <summary>
/// 标记为已启动 /// 标记为已启动
@ -231,8 +209,6 @@ public class CellularNetworkState
IsInitialized = false; IsInitialized = false;
LastStopTime = DateTime.Now; LastStopTime = DateTime.Now;
CurrentStatus = NetworkStatus.Disconnected; CurrentStatus = NetworkStatus.Disconnected;
CurrentSignalStrength = SignalStrength.NoSignal;
CurrentNetworkType = NetworkType.Unknown; CurrentNetworkType = NetworkType.Unknown;
CurrentTransmitPower = 0;
} }
} }

100
CoreAgent.Domain/Entities/NetworkConfiguration.cs

@ -2,11 +2,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization;
namespace CoreAgent.Domain.Entities namespace CoreAgent.Domain.Entities
{ {
/// <summary> /// <summary>
/// 网络配置实体 /// 网络配置聚合根
/// </summary> /// </summary>
public class NetworkConfiguration : IValidatableObject public class NetworkConfiguration : IValidatableObject
{ {
@ -14,25 +15,27 @@ namespace CoreAgent.Domain.Entities
/// 配置键值 /// 配置键值
/// </summary> /// </summary>
[Required(ErrorMessage = "配置键值不能为空")] [Required(ErrorMessage = "配置键值不能为空")]
[JsonPropertyName("configKey")]
public string ConfigKey { get; set; } public string ConfigKey { get; set; }
/// <summary> /// <summary>
/// RAN配置文件路径 /// RAN配置文件路径
/// </summary> /// </summary>
[Required(ErrorMessage = "RAN配置路径不能为空")] [Required(ErrorMessage = "RAN配置路径不能为空")]
[JsonPropertyName("ragConfig")]
public string RagConfig { get; set; } public string RagConfig { get; set; }
/// <summary> /// <summary>
/// 核心网和IMS配置列表 /// 核心网和IMS配置列表
/// </summary> /// </summary>
[Required(ErrorMessage = "核心网和IMS配置不能为空")] [JsonPropertyName("coreOrImsConfigs")]
[MinLength(1, ErrorMessage = "至少需要一个核心网和IMS配置")]
public List<CoreImsConfig> CoreOrImsConfigs { get; set; } public List<CoreImsConfig> CoreOrImsConfigs { get; set; }
/// <summary> /// <summary>
/// APN配置 /// APN配置
/// </summary> /// </summary>
[Required(ErrorMessage = "APN配置不能为空")] [Required(ErrorMessage = "APN配置不能为空")]
[JsonPropertyName("apn")]
public string Apn { get; set; } public string Apn { get; set; }
/// <summary> /// <summary>
@ -40,13 +43,55 @@ namespace CoreAgent.Domain.Entities
/// </summary> /// </summary>
[Required(ErrorMessage = "频段配置不能为空")] [Required(ErrorMessage = "频段配置不能为空")]
[MinLength(1, ErrorMessage = "至少需要一个频段配置")] [MinLength(1, ErrorMessage = "至少需要一个频段配置")]
[JsonPropertyName("band")]
public List<string> Band { get; set; } public List<string> Band { get; set; }
/// <summary> /// <summary>
/// 配置说明 /// 配置说明
/// </summary> /// </summary>
[JsonPropertyName("comment")]
public string Comment { get; set; } public string Comment { get; set; }
/// <summary>
/// 构造函数
/// </summary>
[JsonConstructor]
public NetworkConfiguration()
{
CoreOrImsConfigs = new List<CoreImsConfig>();
Band = new List<string>();
}
/// <summary>
/// 创建新的网络配置
/// </summary>
public static NetworkConfiguration Create(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null)
{
var config = new NetworkConfiguration
{
ConfigKey = configKey,
RagConfig = ragConfig,
Apn = apn,
Comment = comment,
CoreOrImsConfigs = coreOrImsConfigs ?? new List<CoreImsConfig>(),
Band = band ?? new List<string>()
};
var validationResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(config, new ValidationContext(config), validationResults, true))
{
throw new ValidationException(string.Join(Environment.NewLine, validationResults.Select(r => r.ErrorMessage)));
}
return config;
}
/// <summary> /// <summary>
/// 验证配置 /// 验证配置
/// </summary> /// </summary>
@ -97,31 +142,18 @@ namespace CoreAgent.Domain.Entities
{ {
return CoreOrImsConfigs.FirstOrDefault(x => x.Index == index); return CoreOrImsConfigs.FirstOrDefault(x => x.Index == index);
} }
}
/// <summary> /// <summary>
/// 验证配置文件是否存在 /// 网络配置包装类
/// </summary> /// </summary>
public bool ValidateConfigFiles() public class NetworkConfigurationsWrapper
{
if (!System.IO.File.Exists(RagConfig))
{
throw new InvalidOperationException($"RAN配置文件不存在: {RagConfig}");
}
foreach (var config in CoreOrImsConfigs)
{ {
if (!System.IO.File.Exists(config.CoreNetworkConfig)) /// <summary>
{ /// 网络配置列表
throw new InvalidOperationException($"核心网配置文件不存在: {config.CoreNetworkConfig}"); /// </summary>
} [JsonPropertyName("networkConfigurations")]
if (!System.IO.File.Exists(config.ImsConfig)) public List<NetworkConfiguration> NetworkConfigurations { get; set; } = new List<NetworkConfiguration>();
{
throw new InvalidOperationException($"IMS配置文件不存在: {config.ImsConfig}");
}
}
return true;
}
} }
/// <summary> /// <summary>
@ -134,6 +166,7 @@ namespace CoreAgent.Domain.Entities
/// </summary> /// </summary>
[Required(ErrorMessage = "配置索引不能为空")] [Required(ErrorMessage = "配置索引不能为空")]
[Range(1, int.MaxValue, ErrorMessage = "配置索引必须大于0")] [Range(1, int.MaxValue, ErrorMessage = "配置索引必须大于0")]
[JsonPropertyName("index")]
public int Index { get; set; } public int Index { get; set; }
/// <summary> /// <summary>
@ -141,6 +174,7 @@ namespace CoreAgent.Domain.Entities
/// </summary> /// </summary>
[Required(ErrorMessage = "PLMN码不能为空")] [Required(ErrorMessage = "PLMN码不能为空")]
[RegularExpression(@"^\d{5,6}$", ErrorMessage = "PLMN码必须是5-6位数字")] [RegularExpression(@"^\d{5,6}$", ErrorMessage = "PLMN码必须是5-6位数字")]
[JsonPropertyName("plmn")]
public string Plmn { get; set; } public string Plmn { get; set; }
/// <summary> /// <summary>
@ -148,6 +182,7 @@ namespace CoreAgent.Domain.Entities
/// </summary> /// </summary>
[Required(ErrorMessage = "核心网配置路径不能为空")] [Required(ErrorMessage = "核心网配置路径不能为空")]
[RegularExpression(@"^Config/CoreNetwork/.*\.cfg$", ErrorMessage = "核心网配置路径格式不正确")] [RegularExpression(@"^Config/CoreNetwork/.*\.cfg$", ErrorMessage = "核心网配置路径格式不正确")]
[JsonPropertyName("coreNetworkConfig")]
public string CoreNetworkConfig { get; set; } public string CoreNetworkConfig { get; set; }
/// <summary> /// <summary>
@ -155,22 +190,7 @@ namespace CoreAgent.Domain.Entities
/// </summary> /// </summary>
[Required(ErrorMessage = "IMS配置路径不能为空")] [Required(ErrorMessage = "IMS配置路径不能为空")]
[RegularExpression(@"^Config/Ims/.*\.cfg$", ErrorMessage = "IMS配置路径格式不正确")] [RegularExpression(@"^Config/Ims/.*\.cfg$", ErrorMessage = "IMS配置路径格式不正确")]
[JsonPropertyName("imsConfig")]
public string ImsConfig { get; set; } public string ImsConfig { get; set; }
/// <summary>
/// 获取配置文件的完整路径
/// </summary>
public string GetFullCoreNetworkConfigPath()
{
return System.IO.Path.GetFullPath(CoreNetworkConfig);
}
/// <summary>
/// 获取IMS配置文件的完整路径
/// </summary>
public string GetFullImsConfigPath()
{
return System.IO.Path.GetFullPath(ImsConfig);
}
} }
} }

55
CoreAgent.Domain/Interfaces/INetworkConfigurationRepository.cs

@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CoreAgent.Domain.Entities;
namespace CoreAgent.Domain.Interfaces
{
/// <summary>
/// 网络配置仓储接口
/// </summary>
public interface INetworkConfigurationRepository
{
/// <summary>
/// 创建网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <param name="ragConfig">RAN配置文件路径</param>
/// <param name="coreOrImsConfigs">核心网和IMS配置列表</param>
/// <param name="apn">APN配置</param>
/// <param name="band">频段配置</param>
/// <param name="comment">配置说明</param>
/// <returns>创建的网络配置</returns>
Task<NetworkConfiguration> CreateAsync(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null);
/// <summary>
/// 保存网络配置
/// </summary>
/// <param name="configuration">网络配置</param>
Task SaveAsync(NetworkConfiguration configuration);
/// <summary>
/// 删除网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
Task DeleteAsync(string configKey);
/// <summary>
/// 获取所有网络配置
/// </summary>
/// <returns>网络配置列表</returns>
Task<List<NetworkConfiguration>> GetAllAsync();
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <returns>网络配置</returns>
Task<NetworkConfiguration> GetByConfigKeyAsync(string configKey);
}
}

55
CoreAgent.Domain/Interfaces/INetworkConfigurationService.cs

@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CoreAgent.Domain.Entities;
namespace CoreAgent.Domain.Interfaces
{
/// <summary>
/// 网络配置服务接口
/// </summary>
public interface INetworkConfigurationService
{
/// <summary>
/// 创建网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <param name="ragConfig">RAN配置文件路径</param>
/// <param name="coreOrImsConfigs">核心网和IMS配置列表</param>
/// <param name="apn">APN配置</param>
/// <param name="band">频段配置</param>
/// <param name="comment">配置说明</param>
/// <returns>创建的网络配置</returns>
Task<NetworkConfiguration> CreateAsync(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null);
/// <summary>
/// 保存网络配置
/// </summary>
/// <param name="configuration">网络配置</param>
Task SaveAsync(NetworkConfiguration configuration);
/// <summary>
/// 删除网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
Task DeleteAsync(string configKey);
/// <summary>
/// 获取所有网络配置
/// </summary>
/// <returns>网络配置列表</returns>
Task<List<NetworkConfiguration>> GetAllAsync();
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
/// <param name="configKey">配置键值</param>
/// <returns>网络配置</returns>
Task<NetworkConfiguration> GetByConfigKeyAsync(string configKey);
}
}

25
CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs

@ -10,17 +10,15 @@ public interface ICellularNetworkService
/// <summary> /// <summary>
/// 启动蜂窝网络 /// 启动蜂窝网络
/// </summary> /// </summary>
/// <param name="interfaceName">网络接口名称</param> /// <param name="Key">网络配置映射Key</param>
/// <param name="config">网络配置</param>
/// <returns>启动结果</returns> /// <returns>启动结果</returns>
Task<bool> StartAsync(string interfaceName, CellularNetworkConfig config); Task<bool> StartAsync(string Key);
/// <summary> /// <summary>
/// 停止蜂窝网络 /// 停止蜂窝网络
/// </summary> /// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <returns>停止结果</returns> /// <returns>停止结果</returns>
Task<bool> StopAsync(string interfaceName); Task<bool> StopAsync();
} }
/// <summary> /// <summary>
@ -81,24 +79,19 @@ public enum NetworkType
Unknown, Unknown,
/// <summary> /// <summary>
/// 2G网络 /// 4G网络
/// </summary>
G2,
/// <summary>
/// 3G网络
/// </summary> /// </summary>
G3, LTE,
/// <summary> /// <summary>
/// 4G网络 /// 5G网络
/// </summary> /// </summary>
G4, NR,
/// <summary> /// <summary>
/// 5G网络 /// 4+5 G网络
/// </summary> /// </summary>
G5 LTE_NR,
} }
/// <summary> /// <summary>

25
CoreAgent.Domain/Interfaces/Network/INetworkConfigurator.cs

@ -1,25 +0,0 @@
using CoreAgent.Domain.Models.Network;
namespace CoreAgent.Domain.Interfaces.Network;
/// <summary>
/// 网络配置器接口
/// </summary>
public interface INetworkConfigurator
{
/// <summary>
/// 配置网络参数
/// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <param name="config">网络配置</param>
/// <returns>配置结果</returns>
Task<bool> ConfigureAsync(string interfaceName, CellularNetworkConfig config);
/// <summary>
/// 设置发射功率
/// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <param name="powerLevel">功率等级(0-100)</param>
/// <returns>设置结果</returns>
Task<bool> SetTransmitPowerAsync(string interfaceName, int powerLevel);
}

36
CoreAgent.Domain/Interfaces/Network/INetworkStatusProvider.cs

@ -1,36 +0,0 @@
using CoreAgent.Domain.Models.Network;
namespace CoreAgent.Domain.Interfaces.Network;
/// <summary>
/// 网络状态提供者接口
/// </summary>
public interface INetworkStatusProvider
{
/// <summary>
/// 获取网络状态
/// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <returns>网络状态信息</returns>
Task<NetworkStatus> GetNetworkStatusAsync(string interfaceName);
/// <summary>
/// 获取信号强度
/// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <returns>信号强度信息</returns>
Task<SignalStrength> GetSignalStrengthAsync(string interfaceName);
/// <summary>
/// 获取网络类型
/// </summary>
/// <param name="interfaceName">网络接口名称</param>
/// <returns>网络类型信息</returns>
Task<NetworkType> GetNetworkTypeAsync(string interfaceName);
/// <summary>
/// 获取全局状态
/// </summary>
/// <returns>全局状态信息</returns>
Task<CellularNetworkGlobalStatus> GetGlobalStatusAsync();
}

24
CoreAgent.Domain/Models/System/CommandTemplateConfig.cs

@ -30,4 +30,28 @@ public class CommandTemplateConfig
/// </summary> /// </summary>
[JsonPropertyName("isEnabled")] [JsonPropertyName("isEnabled")]
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;
/// <summary>
/// 是否需要返回结果
/// </summary>
[JsonPropertyName("needReturnResult")]
public bool NeedReturnResult { get; set; } = false;
/// <summary>
/// 是否需要后台执行
/// </summary>
[JsonPropertyName("needBackgroundExecution")]
public bool NeedBackgroundExecution { get; set; } = false;
/// <summary>
/// 命令是否可以被终止
/// </summary>
[JsonPropertyName("canBeKilled")]
public bool CanBeKilled { get; set; } = false;
/// <summary>
/// 是否需要带参数
/// </summary>
[JsonPropertyName("hasParameters")]
public bool HasParameters { get; set; } = false;
} }

11
CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs

@ -1,6 +1,9 @@
using CoreAgent.Domain.Interfaces;
using CoreAgent.Domain.Interfaces.Network; using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Infrastructure.Command.Factories; using CoreAgent.Infrastructure.Command.Factories;
using CoreAgent.Infrastructure.Repositories;
using CoreAgent.Infrastructure.Services;
using CoreAgent.Infrastructure.Services.Network; using CoreAgent.Infrastructure.Services.Network;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -27,12 +30,10 @@ public static class CommandServiceExtensions
var factory = sp.GetRequiredService<ISystemCommandExecutorFactory>(); var factory = sp.GetRequiredService<ISystemCommandExecutorFactory>();
return factory.CreateExecutor(); return factory.CreateExecutor();
}); });
// 注册网络配置器 // 注册网络配置器
services.AddScoped<INetworkConfigurator, CellularNetworkConfigurator>(); services.AddScoped<INetworkConfigurationRepository, NetworkConfigurationRepository>();
// 注册网络配置器
// 注册网络状态提供者 services.AddScoped<INetworkConfigurationService, NetworkConfigurationService>();
services.AddScoped<INetworkStatusProvider, CellularNetworkStatusProvider>();
// 注册网络服务 // 注册网络服务
services.AddScoped<ICellularNetworkService, CellularNetworkService>(); services.AddScoped<ICellularNetworkService, CellularNetworkService>();

175
CoreAgent.Infrastructure/Repositories/NetworkConfigurationRepository.cs

@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
using Microsoft.Extensions.Configuration;
namespace CoreAgent.Infrastructure.Repositories
{
/// <summary>
/// 网络配置仓储实现
/// </summary>
public class NetworkConfigurationRepository : INetworkConfigurationRepository
{
private static readonly object _lock = new object();
private readonly string _configFilePath;
private static readonly JsonSerializerOptions _jsonOptions = new()
{
PropertyNameCaseInsensitive = true,
WriteIndented = true,
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip
};
/// <summary>
/// 构造函数
/// </summary>
/// <param name="configuration">配置</param>
public NetworkConfigurationRepository(IConfiguration configuration)
{
var basePath = AppDomain.CurrentDomain.BaseDirectory;
_configFilePath = Path.Combine(basePath, "Configurations", "NetworkConfig.json");
// 确保目录存在
var directory = Path.GetDirectoryName(_configFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
}
/// <summary>
/// 创建网络配置
/// </summary>
public async Task<NetworkConfiguration> CreateAsync(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null)
{
var config = NetworkConfiguration.Create(
configKey,
ragConfig,
coreOrImsConfigs,
apn,
band,
comment
);
await SaveAsync(config);
return config;
}
/// <summary>
/// 保存网络配置
/// </summary>
public async Task SaveAsync(NetworkConfiguration configuration)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
var configs = await GetAllAsync();
var existingConfig = configs.FirstOrDefault(c => c.ConfigKey == configuration.ConfigKey);
if (existingConfig != null)
{
var index = configs.IndexOf(existingConfig);
configs[index] = configuration;
}
else
{
configs.Add(configuration);
}
await SaveConfigurationsAsync(configs);
}
/// <summary>
/// 删除网络配置
/// </summary>
public async Task DeleteAsync(string configKey)
{
if (string.IsNullOrEmpty(configKey))
{
throw new ArgumentException("配置键值不能为空", nameof(configKey));
}
var configs = await GetAllAsync();
var config = configs.FirstOrDefault(c => c.ConfigKey == configKey);
if (config != null)
{
configs.Remove(config);
await SaveConfigurationsAsync(configs);
}
}
/// <summary>
/// 获取所有网络配置
/// </summary>
public async Task<List<NetworkConfiguration>> GetAllAsync()
{
if (!File.Exists(_configFilePath))
{
return new List<NetworkConfiguration>();
}
var json = await File.ReadAllTextAsync(_configFilePath);
try
{
// 验证JSON格式
using (JsonDocument.Parse(json))
{
// JSON格式正确
}
var result = JsonSerializer.Deserialize<NetworkConfigurationsWrapper>(json, _jsonOptions);
if (result == null)
{
throw new JsonException("反序列化结果为null");
}
return result.NetworkConfigurations ?? new List<NetworkConfiguration>();
}
catch (JsonException ex)
{
throw new InvalidOperationException($"JSON反序列化失败: {ex.Message}", ex);
}
}
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
public async Task<NetworkConfiguration> GetByConfigKeyAsync(string configKey)
{
if (string.IsNullOrEmpty(configKey))
{
throw new ArgumentException("配置键值不能为空", nameof(configKey));
}
var configs = await GetAllAsync();
return configs.FirstOrDefault(c => c.ConfigKey == configKey);
}
/// <summary>
/// 保存配置列表
/// </summary>
private async Task SaveConfigurationsAsync(List<NetworkConfiguration> configurations)
{
if (configurations == null)
{
throw new ArgumentNullException(nameof(configurations));
}
var json = JsonSerializer.Serialize(new { networkConfigurations = configurations }, _jsonOptions);
await File.WriteAllTextAsync(_configFilePath, json);
}
}
}

110
CoreAgent.Infrastructure/Services/Network/CellularNetworkConfigurator.cs

@ -1,110 +0,0 @@
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network;
/// <summary>
/// 蜂窝网络配置器实现
/// </summary>
public class CellularNetworkConfigurator : INetworkConfigurator
{
private readonly ILogger<CellularNetworkConfigurator> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
public CellularNetworkConfigurator(
ILogger<CellularNetworkConfigurator> logger,
ISystemCommandExecutor commandExecutor)
{
_logger = logger;
_commandExecutor = commandExecutor;
}
public async Task<bool> ConfigureAsync(string interfaceName, CellularNetworkConfig config)
{
try
{
_logger.LogInformation("正在配置蜂窝网络接口: {InterfaceName}", interfaceName);
// 1. 配置APN
if (!string.IsNullOrEmpty(config.Apn))
{
var apnResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" apn=\"{config.Apn}\"");
if (!apnResult)
{
_logger.LogError("配置APN失败");
return false;
}
}
// 2. 配置认证信息
if (!string.IsNullOrEmpty(config.Username) && !string.IsNullOrEmpty(config.Password))
{
var authResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" username=\"{config.Username}\" password=\"{config.Password}\"");
if (!authResult)
{
_logger.LogError("配置认证信息失败");
return false;
}
}
// 3. 配置网络类型
//if (config.NetworkType != NetworkType.Auto)
//{
// var networkTypeResult = await ExecuteCommandAsync(
// $"netsh interface cellular set networktype \"{interfaceName}\" " +
// $"type={(int)config.NetworkType}");
// if (!networkTypeResult)
// {
// _logger.LogError("配置网络类型失败");
// return false;
// }
//}
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 配置成功", interfaceName);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "配置蜂窝网络接口 {InterfaceName} 失败", interfaceName);
return false;
}
}
public async Task<bool> SetTransmitPowerAsync(string interfaceName, int powerLevel)
{
try
{
if (powerLevel < 0 || powerLevel > 100)
{
_logger.LogWarning("发射功率设置无效: {PowerLevel}", powerLevel);
return false;
}
_logger.LogInformation("正在设置蜂窝网络发射功率: {InterfaceName}, {PowerLevel}", interfaceName, powerLevel);
// 设置发射功率
var result = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" power={powerLevel}");
if (!result)
{
_logger.LogError("设置蜂窝网络发射功率失败");
return false;
}
_logger.LogInformation("蜂窝网络发射功率设置成功: {PowerLevel}", powerLevel);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "设置蜂窝网络发射功率失败: {InterfaceName}, {PowerLevel}", interfaceName, powerLevel);
return false;
}
}
private async Task<bool> ExecuteCommandAsync(string command)
{
var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource());
return result.IsSuccess;
}
}

349
CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

@ -1,4 +1,7 @@
using CliWrap;
using CoreAgent.Domain.Contexts; using CoreAgent.Domain.Contexts;
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
using CoreAgent.Domain.Interfaces.Network; using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network; using CoreAgent.Domain.Models.Network;
@ -14,27 +17,36 @@ public class CellularNetworkService : ICellularNetworkService
{ {
private readonly ILogger<CellularNetworkService> _logger; private readonly ILogger<CellularNetworkService> _logger;
private readonly ISystemCommandExecutor _commandExecutor; private readonly ISystemCommandExecutor _commandExecutor;
private readonly INetworkConfigurator _configurator; private readonly INetworkConfigurationService _configService;
private readonly CellularNetworkContext _context; private readonly CellularNetworkContext _context;
private static readonly SemaphoreSlim _startLock = new(1, 1); private static readonly SemaphoreSlim _startLock = new(1, 1);
private const string DefaultInterfaceName = "Cellular";
private const int MaxConnectionAttempts = 30;
private const int ConnectionCheckDelayMs = 1000;
private const int LockTimeoutSeconds = 5;
public CellularNetworkService( public CellularNetworkService(
ILogger<CellularNetworkService> logger, ILogger<CellularNetworkService> logger,
ISystemCommandExecutor commandExecutor, ISystemCommandExecutor commandExecutor,
INetworkConfigurator configurator) INetworkConfigurationService configService)
{ {
_logger = logger; _logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor; _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
_configurator = configurator; _configService = configService ?? throw new ArgumentNullException(nameof(configService));
_context = CellularNetworkContext.Instance; _context = CellularNetworkContext.Instance;
} }
public async Task<bool> StartAsync(string interfaceName, CellularNetworkConfig config) public async Task<bool> StartAsync(string key)
{ {
if (string.IsNullOrEmpty(key))
{
_logger.LogError("启动蜂窝网络失败:配置键为空");
return false;
}
try try
{ {
// 使用信号量确保只能启动一次 if (!await _startLock.WaitAsync(TimeSpan.FromSeconds(LockTimeoutSeconds)))
if (!await _startLock.WaitAsync(TimeSpan.FromSeconds(5)))
{ {
_logger.LogWarning("蜂窝网络启动操作被锁定,可能已有其他启动操作正在进行"); _logger.LogWarning("蜂窝网络启动操作被锁定,可能已有其他启动操作正在进行");
return false; return false;
@ -42,121 +54,338 @@ public class CellularNetworkService : ICellularNetworkService
try try
{ {
return await StartInternalAsync(key);
}
finally
{
_startLock.Release();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "启动蜂窝网络接口失败");
return false;
}
}
public async Task<bool> StopAsync()
{
string NeConfigKey = _context.GetNeConfigKey();
try
{
// 1. 检查网络状态
var state = _context.GetOrCreateNetworkState(NeConfigKey);
if (!state.IsInitialized)
{
_logger.LogWarning("蜂窝网络未初始化,无需停止");
return true;
}
// 2. 执行初始化命令
await ExecuteInitializeCommandsAsync();
// 3. 执行停止命令
_logger.LogInformation("正在执行停止命令: {InterfaceName}", NeConfigKey);
var commands = _context.GetNetworkCommandConfig(); var commands = _context.GetNetworkCommandConfig();
if (commands?.NetworkCommands != null)
{
var stopCommands = commands.NetworkCommands
.Where(s => s.Type == NetworkCommandType.Stop)
.ToArray();
var state = _context.GetOrCreateNetworkState(interfaceName); foreach (var cmd in stopCommands)
if (state.IsInitialized) {
if (!await ExecuteCommandAsync(cmd))
{
_logger.LogWarning("停止命令执行失败: {Template}", cmd.Template);
}
}
}
// 4. 停止网络接口
if (!await DisableNetworkInterfaceAsync(NeConfigKey))
{ {
_logger.LogWarning("蜂窝网络已经初始化,不能重复启动");
return false; return false;
} }
_logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", interfaceName); // 5. 更新状态
state.MarkAsStopped();
_logger.LogInformation($"蜂窝网络 {NeConfigKey} 停止成功");
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, $"停止蜂窝网络 {NeConfigKey} 失败");
return false;
}
}
// 1. 配置网络参数 private async Task<bool> StartInternalAsync(string key)
var configResult = await _configurator.ConfigureAsync(interfaceName, config);
if (!configResult)
{ {
_logger.LogError("配置蜂窝网络参数失败"); // 1. 获取并验证配置
var config = await _configService.GetByConfigKeyAsync(key);
if (config == null)
{
_logger.LogError("未找到网络配置: {ConfigKey}", key);
return false; return false;
} }
// 2. 启动网络接口 // 2. 检查网络状态
var startResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" admin=enable"); var state = _context.GetOrCreateNetworkState(DefaultInterfaceName);
if (!startResult) if (state.IsInitialized)
{ {
_logger.LogError("启动蜂窝网络接口失败"); _logger.LogWarning("蜂窝网络已经初始化,不能重复启动");
return false; return false;
} }
// 3. 等待网络连接 // 3. 执行初始化命令
var connected = await WaitForConnectionAsync(interfaceName); await ExecuteInitializeCommandsAsync();
if (!connected)
// 4. 启动网络接口
_logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", DefaultInterfaceName);
if (!await EnableNetworkInterfaceAsync(config))
{ {
_logger.LogError("蜂窝网络连接超时");
return false; return false;
} }
// 4. 更新状态 // 5. 等待连接
state.UpdateConfig(config); if (!await WaitForConnectionAsync(DefaultInterfaceName))
state.MarkAsStarted(); {
return false;
}
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", interfaceName); // 6. 更新状态
state.MarkAsStarted();
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", DefaultInterfaceName);
return true; return true;
} }
finally
private async Task ExecuteInitializeCommandsAsync()
{ {
_startLock.Release();
var commands = _context.GetNetworkCommandConfig();
if (commands?.NetworkCommands != null)
{
var initCommands = commands.NetworkCommands
.Where(s => s.Type == NetworkCommandType.Initialize)
.ToArray();
foreach (var cmd in initCommands)
{
if (!await ExecuteCommandAsync(cmd))
{
_logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template);
}
} }
} }
}
private async Task<bool> ExecuteCommandAsync(CommandTemplateConfig command)
{
try
{
if (command.CanBeKilled)
{
await KillProcessAsync(command.Template);
}
var result = await _commandExecutor.ExecuteCommandAsync(command.Template, _context.token);
return result.IsSuccess;
}
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "启动蜂窝网络接口 {InterfaceName} 失败", interfaceName); _logger.LogError(ex, "执行命令失败: {Template}", command.Template);
return false; return false;
} }
} }
public async Task<bool> StopAsync(string interfaceName) private async Task KillProcessAsync(string template)
{
string killCmd = $"ps -ef | grep {template} | grep -v grep | awk '{{print $2}}' | xargs kill -9";
await _commandExecutor.ExecuteCommandAsync(killCmd, new CancellationTokenSource());
_logger.LogInformation("已终止进程: {Template}", template);
}
private async Task<bool> EnableNetworkInterfaceAsync(NetworkConfiguration networkConfig)
{ {
try try
{ {
var state = _context.GetOrCreateNetworkState(interfaceName); var commands = _context.GetNetworkCommandConfig();
if (!state.IsInitialized) var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.Start);
if (startCommand == null)
{ {
_logger.LogWarning("蜂窝网络未初始化,无需停止"); _logger.LogError("未找到启动命令配置");
return true; return false;
} }
_logger.LogInformation("正在停止蜂窝网络接口: {InterfaceName}", interfaceName); // 根据配置类型执行不同的启动命令
if (HasBothRagAndCoreConfigs(networkConfig))
{
return await ExecuteFullConfigStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyRagConfig(networkConfig))
{
return await ExecuteRagOnlyStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyCoreConfigs(networkConfig))
{
return await ExecuteCoreOnlyStartCommandsAsync(startCommand, networkConfig);
}
// 1. 停止网络接口 _logger.LogWarning("无有效配置,跳过启动");
var stopResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" admin=disable"); return false;
if (!stopResult) }
catch (Exception ex)
{ {
_logger.LogError("停止蜂窝网络接口失败"); _logger.LogError(ex, "启动网络接口失败");
return false; return false;
} }
}
// 2. 更新状态 private bool HasBothRagAndCoreConfigs(NetworkConfiguration config)
state.MarkAsStopped(); {
return !string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
}
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 停止成功", interfaceName); private bool HasOnlyRagConfig(NetworkConfiguration config)
return true; {
return !string.IsNullOrWhiteSpace(config.RagConfig) && !config.CoreOrImsConfigs.Any();
} }
catch (Exception ex)
private bool HasOnlyCoreConfigs(NetworkConfiguration config)
{ {
_logger.LogError(ex, "停止蜂窝网络接口 {InterfaceName} 失败", interfaceName); return string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
return false; }
private async Task<bool> ExecuteFullConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
if (networkConfig.CoreOrImsConfigs.Count == 1)
{
return await ExecuteSingleConfigStartCommandAsync(startCommand, networkConfig);
} }
return await ExecuteMultiConfigStartCommandsAsync(startCommand, networkConfig);
} }
private async Task<bool> WaitForConnectionAsync(string interfaceName) private async Task<bool> ExecuteRagOnlyStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{ {
const int maxAttempts = 30; var command = string.Format(startCommand.Template, 1);
const int delayMs = 1000; var fullCommand = $"{command} {networkConfig.RagConfig}";
for (int i = 0; i < maxAttempts; i++) _logger.LogInformation("执行RAG配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.token);
return result.IsSuccess;
}
private async Task<bool> ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{ {
var status = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\""); var commands = new List<string>();
if (status.IsSuccess && status.Output.Contains("已连接", StringComparison.OrdinalIgnoreCase)) var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
for (int i = 0; i < secondaryConfigs.Length; i++)
{ {
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 1);
commands.Add($"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}");
}
foreach (var command in commands)
{
_logger.LogInformation("执行核心网配置启动命令: {Command}", command);
var result = await _commandExecutor.ExecuteCommandAsync(command, _context.token);
if (!result.IsSuccess)
{
_logger.LogWarning("命令执行失败: {Command}", command);
return false;
}
}
return true; return true;
} }
await Task.Delay(delayMs); private async Task<bool> ExecuteSingleConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var config = networkConfig.CoreOrImsConfigs.First();
var command = string.Format(startCommand.Template, 1);
var fullCommand = $"{command} {networkConfig.RagConfig} {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("执行单配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.token);
return result.IsSuccess;
}
private async Task<bool> ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var commands = new List<string>();
// 添加主配置命令
var primaryConfig = networkConfig.CoreOrImsConfigs.FirstOrDefault(s => s.Index == 1);
if (primaryConfig != null)
{
var primaryCommand = string.Format(startCommand.Template, 1);
commands.Add($"{primaryCommand} {networkConfig.RagConfig} {primaryConfig.CoreNetworkConfig} {primaryConfig.ImsConfig}");
}
// 添加次要配置命令
var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
for (int i = 0; i < secondaryConfigs.Length; i++)
{
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 2);
commands.Add($"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}");
} }
// 添加RAG配置命令
var ragCommand = string.Format(startCommand.Template, 1);
commands.Add($"{ragCommand} {networkConfig.RagConfig}");
// 执行所有命令
foreach (var command in commands)
{
_logger.LogInformation("执行多配置启动命令: {Command}", command);
var result = await _commandExecutor.ExecuteCommandAsync(command, _context.token);
if (!result.IsSuccess)
{
_logger.LogWarning("命令执行失败: {Command}", command);
return false; return false;
} }
}
return true;
}
private async Task<bool> ExecuteCommandAsync(string command) private async Task<bool> DisableNetworkInterfaceAsync(string interfaceName)
{ {
var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); var result = await _commandExecutor.ExecuteCommandAsync(
return result.IsSuccess; $"netsh interface cellular set interface \"{interfaceName}\" admin=disable",
new CancellationTokenSource());
if (!result.IsSuccess)
{
_logger.LogError("停止蜂窝网络接口失败");
return false;
}
return true;
} }
private async Task<CommandExecutionResult> ExecuteCommandWithResultAsync(string command) private async Task<bool> WaitForConnectionAsync(string interfaceName)
{ {
return await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); for (int i = 0; i < MaxConnectionAttempts; i++)
{
var status = await _commandExecutor.ExecuteCommandAsync(
$"netsh interface cellular show interfaces \"{interfaceName}\"",
new CancellationTokenSource());
if (status.IsSuccess && status.Output.Contains("已连接", StringComparison.OrdinalIgnoreCase))
{
return true;
}
await Task.Delay(ConnectionCheckDelayMs);
}
_logger.LogError("蜂窝网络连接超时");
return false;
} }
} }

244
CoreAgent.Infrastructure/Services/Network/CellularNetworkStatusProvider.cs

@ -1,244 +0,0 @@
using CoreAgent.Domain.Contexts;
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network;
/// <summary>
/// 蜂窝网络状态提供者实现
/// </summary>
public class CellularNetworkStatusProvider : INetworkStatusProvider
{
private readonly ILogger<CellularNetworkStatusProvider> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
private readonly CellularNetworkContext _context;
public CellularNetworkStatusProvider(
ILogger<CellularNetworkStatusProvider> logger,
ISystemCommandExecutor commandExecutor)
{
_logger = logger;
_commandExecutor = commandExecutor;
_context = CellularNetworkContext.Instance;
}
public async Task<NetworkStatus> GetNetworkStatusAsync(string interfaceName)
{
try
{
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络状态失败");
return NetworkStatus.Unknown;
}
var state = _context.GetOrCreateNetworkState(interfaceName);
var status = ParseNetworkStatus(result.Output);
state.UpdateStatus(status);
return status;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络状态失败");
return NetworkStatus.Unknown;
}
}
public async Task<SignalStrength> GetSignalStrengthAsync(string interfaceName)
{
try
{
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络信号强度失败");
return SignalStrength.NoSignal;
}
var state = _context.GetOrCreateNetworkState(interfaceName);
var strength = ParseSignalStrength(result.Output);
state.UpdateSignalStrength(strength);
return strength;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络信号强度失败");
return SignalStrength.NoSignal;
}
}
public async Task<NetworkType> GetNetworkTypeAsync(string interfaceName)
{
try
{
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络类型失败");
return NetworkType.Unknown;
}
var state = _context.GetOrCreateNetworkState(interfaceName);
var type = ParseNetworkType(result.Output);
state.UpdateNetworkType(type);
return type;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络类型失败");
return NetworkType.Unknown;
}
}
public async Task<CellularNetworkGlobalStatus> GetGlobalStatusAsync()
{
try
{
var result = await ExecuteCommandWithResultAsync("netsh interface cellular show interfaces");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络全局状态失败");
return new CellularNetworkGlobalStatus
{
IsInitialized = false,
CurrentStatus = NetworkStatus.Unknown,
CurrentSignalStrength = SignalStrength.NoSignal,
CurrentNetworkType = NetworkType.Unknown,
CurrentTransmitPower = 0
};
}
// 解析所有接口的状态
var interfaces = ParseInterfaces(result.Output);
foreach (var iface in interfaces)
{
var state = _context.GetOrCreateNetworkState(iface.Name);
state.UpdateStatus(iface.Status);
state.UpdateSignalStrength(iface.SignalStrength);
state.UpdateNetworkType(iface.NetworkType);
}
// 聚合所有接口的状态
var states = _context.GetAllNetworkStates();
return new CellularNetworkGlobalStatus
{
IsInitialized = states.Any(s => s.IsInitialized),
LastStartTime = states.Max(s => s.LastStartTime),
LastStopTime = states.Max(s => s.LastStopTime),
CurrentStatus = states.FirstOrDefault()?.CurrentStatus ?? NetworkStatus.Unknown,
CurrentSignalStrength = states.FirstOrDefault()?.CurrentSignalStrength ?? SignalStrength.NoSignal,
CurrentNetworkType = states.FirstOrDefault()?.CurrentNetworkType ?? NetworkType.Unknown,
CurrentTransmitPower = states.FirstOrDefault()?.CurrentTransmitPower ?? 0
};
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络全局状态失败");
return new CellularNetworkGlobalStatus
{
IsInitialized = false,
CurrentStatus = NetworkStatus.Unknown,
CurrentSignalStrength = SignalStrength.NoSignal,
CurrentNetworkType = NetworkType.Unknown,
CurrentTransmitPower = 0
};
}
}
private async Task<CommandExecutionResult> ExecuteCommandWithResultAsync(string command)
{
return await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource());
}
private NetworkStatus ParseNetworkStatus(string output)
{
if (output.Contains("已连接", StringComparison.OrdinalIgnoreCase))
return NetworkStatus.Connected;
if (output.Contains("已断开", StringComparison.OrdinalIgnoreCase))
return NetworkStatus.Disconnected;
return NetworkStatus.Unknown;
}
private SignalStrength ParseSignalStrength(string output)
{
if (output.Contains("信号强度: 强", StringComparison.OrdinalIgnoreCase))
return SignalStrength.Strong;
if (output.Contains("信号强度: 中", StringComparison.OrdinalIgnoreCase))
return SignalStrength.Medium;
if (output.Contains("信号强度: 弱", StringComparison.OrdinalIgnoreCase))
return SignalStrength.Weak;
return SignalStrength.NoSignal;
}
private NetworkType ParseNetworkType(string output)
{
if (output.Contains("5G", StringComparison.OrdinalIgnoreCase))
return NetworkType.G5;
if (output.Contains("4G", StringComparison.OrdinalIgnoreCase))
return NetworkType.G4;
if (output.Contains("3G", StringComparison.OrdinalIgnoreCase))
return NetworkType.G3;
if (output.Contains("2G", StringComparison.OrdinalIgnoreCase))
return NetworkType.G2;
return NetworkType.Unknown;
}
private class InterfaceInfo
{
public string Name { get; set; }
public NetworkStatus Status { get; set; }
public SignalStrength SignalStrength { get; set; }
public NetworkType NetworkType { get; set; }
}
private IEnumerable<InterfaceInfo> ParseInterfaces(string output)
{
var interfaces = new List<InterfaceInfo>();
var lines = output.Split('\n');
InterfaceInfo currentInterface = null;
foreach (var line in lines)
{
if (line.Contains("接口名称:", StringComparison.OrdinalIgnoreCase))
{
if (currentInterface != null)
{
interfaces.Add(currentInterface);
}
currentInterface = new InterfaceInfo
{
Name = line.Split(':')[1].Trim(),
Status = NetworkStatus.Unknown,
SignalStrength = SignalStrength.NoSignal,
NetworkType = NetworkType.Unknown
};
}
else if (currentInterface != null)
{
if (line.Contains("状态:", StringComparison.OrdinalIgnoreCase))
{
currentInterface.Status = ParseNetworkStatus(line);
}
else if (line.Contains("信号强度:", StringComparison.OrdinalIgnoreCase))
{
currentInterface.SignalStrength = ParseSignalStrength(line);
}
else if (line.Contains("网络类型:", StringComparison.OrdinalIgnoreCase))
{
currentInterface.NetworkType = ParseNetworkType(line);
}
}
}
if (currentInterface != null)
{
interfaces.Add(currentInterface);
}
return interfaces;
}
}

13
CoreAgent.Infrastructure/Services/Network/Extensions/ServiceCollectionExtensions.cs

@ -0,0 +1,13 @@
using CoreAgent.Domain.Interfaces.Network;
using Microsoft.Extensions.DependencyInjection;
namespace CoreAgent.Infrastructure.Services.Network.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddNetworkServices(this IServiceCollection services)
{
services.AddScoped<ICellularNetworkService, CellularNetworkService>();
return services;
}
}

70
CoreAgent.Infrastructure/Services/NetworkConfigurationService.cs

@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
namespace CoreAgent.Infrastructure.Services
{
/// <summary>
/// 网络配置服务实现
/// </summary>
public class NetworkConfigurationService : INetworkConfigurationService
{
private readonly INetworkConfigurationRepository _repository;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="repository">网络配置仓储</param>
public NetworkConfigurationService(INetworkConfigurationRepository repository)
{
_repository = repository;
}
/// <summary>
/// 创建网络配置
/// </summary>
public Task<NetworkConfiguration> CreateAsync(
string configKey,
string ragConfig,
List<CoreImsConfig> coreOrImsConfigs,
string apn,
List<string> band,
string comment = null)
{
return _repository.CreateAsync(configKey, ragConfig, coreOrImsConfigs, apn, band, comment);
}
/// <summary>
/// 保存网络配置
/// </summary>
public Task SaveAsync(NetworkConfiguration configuration)
{
return _repository.SaveAsync(configuration);
}
/// <summary>
/// 删除网络配置
/// </summary>
public Task DeleteAsync(string configKey)
{
return _repository.DeleteAsync(configKey);
}
/// <summary>
/// 获取所有网络配置
/// </summary>
public Task<List<NetworkConfiguration>> GetAllAsync()
{
return _repository.GetAllAsync();
}
/// <summary>
/// 根据配置键获取网络配置
/// </summary>
public Task<NetworkConfiguration> GetByConfigKeyAsync(string configKey)
{
return _repository.GetByConfigKeyAsync(configKey);
}
}
}
Loading…
Cancel
Save