diff --git a/CoreAgent.API/Configurations/NetworkConfig.json b/CoreAgent.API/Configurations/NetworkConfig.json index 599b9d1..a3a8dce 100644 --- a/CoreAgent.API/Configurations/NetworkConfig.json +++ b/CoreAgent.API/Configurations/NetworkConfig.json @@ -1,26 +1,30 @@ { - "configKey": "Default", - "ragConfig": "Config/Ran/default.cfg", - "coreOrImsConfigs": [ + "networkConfigurations": [ { - "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" + "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": "默认网络配置" } - ], - "apn": "Internet", - "band": [ - "B1", - "B3", - "B5", - "B8" - ], - "comment": "默认网络配置" + ] } \ No newline at end of file diff --git a/CoreAgent.API/Configurations/netcommand.json b/CoreAgent.API/Configurations/netcommand.json index 938dc67..4e15f8a 100644 --- a/CoreAgent.API/Configurations/netcommand.json +++ b/CoreAgent.API/Configurations/netcommand.json @@ -1,62 +1,158 @@ { - "NetworkCommand": { - "DefaultRetryCount": 3, - "DefaultRetryInterval": 1000, - "NetworkCommands": [ - { - "type": 1, - "template": "network init", - "timeout": 30000, - "isEnabled": true - }, - { - "type": 1, - "template": "network check", - "timeout": 15000, - "isEnabled": true - }, - { - "type": 1, - "template": "network verify", - "timeout": 20000, - "isEnabled": true - }, - { - "type": 2, - "template": "network start", - "timeout": 25000, - "isEnabled": true - }, - { - "type": 2, - "template": "network resume", - "timeout": 20000, - "isEnabled": true - }, - { - "type": 3, - "template": "network stop", - "timeout": 8000, - "isEnabled": true - }, - { - "type": 3, - "template": "network cleanup", - "timeout": 5000, - "isEnabled": true - }, - { - "type": 4, - "template": "network status", - "timeout": 5000, - "isEnabled": true - }, - { - "type": 4, - "template": "network info", - "timeout": 5000, - "isEnabled": true - } - ] - } -} \ No newline at end of file + "NetworkCommand": { + "DefaultRetryCount": 3, + "DefaultRetryInterval": 1000, + "NetworkCommands": [ + { + "type": 0, + "template": "lte", + "timeout": 5000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": true, + "hasParameters": false + }, + { + "type": 0, + "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, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "chmod 777 /root/enb/lte_init.sh", + "timeout": 5000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "chmod 777 /root/mme/lte_init.sh", + "timeout": 5000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "sh /root/enb/lte_init.sh", + "timeout": 20000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "sh /root/mme/lte_init.sh", + "timeout": 20000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "rm -f /tmp/*", + "timeout": 5000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "rm -f /var/log/lte/*", + "timeout": 5000, + "isEnabled": true, + "needReturnResult": false, + "needBackgroundExecution": false, + "canBeKilled": false, + "hasParameters": false + }, + { + "type": 0, + "template": "killall screen", + "timeout": 2000, + "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 + } + ] + } +} diff --git a/CoreAgent.API/Controllers/CellularNetworkController.cs b/CoreAgent.API/Controllers/CellularNetworkController.cs index d7a577c..eed4601 100644 --- a/CoreAgent.API/Controllers/CellularNetworkController.cs +++ b/CoreAgent.API/Controllers/CellularNetworkController.cs @@ -8,9 +8,7 @@ namespace CoreAgent.API.Controllers; /// /// 蜂窝网络控制器 /// -[ApiController] [ApiVersion("1.0")] -[Route("api/v{version:apiVersion}/[controller]")] public class CellularNetworkController : BaseApiController { private readonly ILogger _logger; @@ -30,7 +28,7 @@ public class CellularNetworkController : BaseApiController [HttpPost("start")] public async Task Start([FromBody] StartCellularNetworkCommand command) { - _logger.LogInformation("收到启动蜂窝网络请求: {InterfaceName}", command.InterfaceName); + _logger.LogInformation("收到启动蜂窝网络请求: {InterfaceName}", command.Key); return await HandleRequest(command); } diff --git a/CoreAgent.API/Controllers/NetworkConfigController.cs b/CoreAgent.API/Controllers/NetworkConfigController.cs new file mode 100644 index 0000000..97d23a9 --- /dev/null +++ b/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 +{ + /// + /// 网络配置控制器 + /// + [ApiVersion("1.0")] + public class NetworkConfigController : BaseApiController + { + /// + /// 构造函数 + /// + /// 中介者 + /// 日志记录器 + public NetworkConfigController(IMediator mediator, ILogger logger) + : base(mediator, logger) + { + } + + /// + /// 获取所有网络配置 + /// + /// 网络配置列表 + [HttpGet] + [ProducesResponseType(typeof(List), 200)] + public async Task GetAll() + { + return await HandleRequest>( + new GetAllNetworkConfigurationsQuery()); + } + + /// + /// 根据配置键获取网络配置 + /// + /// 配置键值 + /// 网络配置 + [HttpGet("{configKey}")] + [ProducesResponseType(typeof(NetworkConfiguration), 200)] + [ProducesResponseType(404)] + public async Task GetByKey(string configKey) + { + return await HandleRequest( + new GetNetworkConfigurationByKeyQuery { ConfigKey = configKey }); + } + + /// + /// 创建网络配置 + /// + /// 创建网络配置命令 + /// 创建的网络配置 + [HttpPost] + [ProducesResponseType(typeof(NetworkConfiguration), 201)] + [ProducesResponseType(400)] + public async Task Create([FromBody] CreateNetworkConfigurationCommand command) + { + var result = await HandleRequest(command); + if (result is OkObjectResult okResult) + { + return CreatedAtAction(nameof(GetByKey), + new { configKey = command.ConfigKey }, + okResult.Value); + } + return result; + } + + /// + /// 删除网络配置 + /// + /// 配置键值 + /// 操作结果 + [HttpDelete("{configKey}")] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public async Task Delete(string configKey) + { + var command = new DeleteNetworkConfigurationCommand { ConfigKey = configKey }; + return await HandleRequest(command); + } + } +} \ No newline at end of file diff --git a/CoreAgent.API/logs/log-20250611.txt b/CoreAgent.API/logs/log-20250611.txt index 9839326..66a83ac 100644 --- a/CoreAgent.API/logs/log-20250611.txt +++ b/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.108 +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 diff --git a/CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs b/CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs index dd73727..6ea2697 100644 --- a/CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs +++ b/CoreAgent.Application/Commands/CellularNetwork/StartCellularNetworkCommand.cs @@ -12,9 +12,4 @@ public class StartCellularNetworkCommand : IRequest /// 网络接口名称 /// public string Key { get; set; } - - /// - /// 网络配置 - /// - public CellularNetworkConfig Config { get; set; } } \ No newline at end of file diff --git a/CoreAgent.Application/Commands/NetworkConfig/CreateNetworkConfigurationCommand.cs b/CoreAgent.Application/Commands/NetworkConfig/CreateNetworkConfigurationCommand.cs new file mode 100644 index 0000000..4448b86 --- /dev/null +++ b/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 +{ + /// + /// 创建网络配置命令 + /// + public class CreateNetworkConfigurationCommand : IRequest + { + /// + /// 配置键值 + /// + public string ConfigKey { get; set; } + + /// + /// RAN配置文件路径 + /// + public string RagConfig { get; set; } + + /// + /// 核心网和IMS配置列表 + /// + public List CoreOrImsConfigs { get; set; } + + /// + /// APN配置 + /// + public string Apn { get; set; } + + /// + /// 频段配置 + /// + public List Band { get; set; } + + /// + /// 配置说明 + /// + public string Comment { get; set; } + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Commands/NetworkConfig/DeleteNetworkConfigurationCommand.cs b/CoreAgent.Application/Commands/NetworkConfig/DeleteNetworkConfigurationCommand.cs new file mode 100644 index 0000000..4d998d5 --- /dev/null +++ b/CoreAgent.Application/Commands/NetworkConfig/DeleteNetworkConfigurationCommand.cs @@ -0,0 +1,15 @@ +using MediatR; + +namespace CoreAgent.Application.Commands.NetworkConfig +{ + /// + /// 删除网络配置命令 + /// + public class DeleteNetworkConfigurationCommand : IRequest + { + /// + /// 配置键值 + /// + public string ConfigKey { get; set; } + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs b/CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs index 3beea10..d4a323e 100644 --- a/CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs +++ b/CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs @@ -25,14 +25,14 @@ public class StartCellularNetworkCommandHandler : IRequestHandler + /// 创建网络配置命令 + /// + public class CreateNetworkConfigurationCommand : IRequest + { + /// + /// 配置键值 + /// + public string ConfigKey { get; set; } + + /// + /// RAN配置文件路径 + /// + public string RagConfig { get; set; } + + /// + /// 核心网和IMS配置列表 + /// + public List CoreOrImsConfigs { get; set; } + + /// + /// APN配置 + /// + public string Apn { get; set; } + + /// + /// 频段配置 + /// + public List Band { get; set; } + + /// + /// 配置说明 + /// + public string Comment { get; set; } + } + + /// + /// 创建网络配置命令处理器 + /// + public class CreateNetworkConfigurationCommandHandler : IRequestHandler + { + private readonly INetworkConfigurationService _service; + + /// + /// 构造函数 + /// + /// 网络配置服务 + public CreateNetworkConfigurationCommandHandler(INetworkConfigurationService service) + { + _service = service; + } + + /// + /// 处理创建网络配置命令 + /// + /// 创建网络配置命令 + /// 取消令牌 + /// 创建的网络配置 + public async Task Handle(CreateNetworkConfigurationCommand request, CancellationToken cancellationToken) + { + return await _service.CreateAsync( + request.ConfigKey, + request.RagConfig, + request.CoreOrImsConfigs, + request.Apn, + request.Band, + request.Comment + ); + } + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs b/CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs new file mode 100644 index 0000000..6b8f2d9 --- /dev/null +++ b/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 +{ + + /// + /// 删除网络配置命令处理器 + /// + public class DeleteNetworkConfigurationCommandHandler : IRequestHandler + { + private readonly INetworkConfigurationService _service; + + /// + /// 构造函数 + /// + /// 网络配置服务 + public DeleteNetworkConfigurationCommandHandler(INetworkConfigurationService service) + { + _service = service; + } + + /// + /// 处理删除网络配置命令 + /// + /// 删除网络配置命令 + /// 取消令牌 + /// 操作结果 + public async Task Handle(DeleteNetworkConfigurationCommand request, CancellationToken cancellationToken) + { + await _service.DeleteAsync(request.ConfigKey); + return Unit.Value; + } + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Handlers/NetworkConfig/Queries/GetNetworkConfigurationQueryHandler.cs b/CoreAgent.Application/Handlers/NetworkConfig/Queries/GetNetworkConfigurationQueryHandler.cs new file mode 100644 index 0000000..ecc4d04 --- /dev/null +++ b/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 +{ + /// + /// 获取所有网络配置查询处理器 + /// + public class GetAllNetworkConfigurationsQueryHandler : IRequestHandler> + { + private readonly INetworkConfigurationService _service; + + /// + /// 构造函数 + /// + /// 网络配置服务 + public GetAllNetworkConfigurationsQueryHandler(INetworkConfigurationService service) + { + _service = service; + } + + /// + /// 处理获取所有网络配置查询 + /// + /// 获取所有网络配置查询 + /// 取消令牌 + /// 网络配置列表 + public Task> Handle(GetAllNetworkConfigurationsQuery request, CancellationToken cancellationToken) + { + return _service.GetAllAsync(); + } + } + + /// + /// 根据配置键获取网络配置查询处理器 + /// + public class GetNetworkConfigurationByKeyQueryHandler : IRequestHandler + { + private readonly INetworkConfigurationService _service; + + /// + /// 构造函数 + /// + /// 网络配置服务 + public GetNetworkConfigurationByKeyQueryHandler(INetworkConfigurationService service) + { + _service = service; + } + + /// + /// 处理根据配置键获取网络配置查询 + /// + /// 根据配置键获取网络配置查询 + /// 取消令牌 + /// 网络配置 + public Task Handle(GetNetworkConfigurationByKeyQuery request, CancellationToken cancellationToken) + { + return _service.GetByConfigKeyAsync(request.ConfigKey); + } + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Interfaces/INetworkConfigurationService.cs b/CoreAgent.Application/Interfaces/INetworkConfigurationService.cs new file mode 100644 index 0000000..1a024c4 --- /dev/null +++ b/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 +{ + /// + /// 网络配置服务接口 + /// + public interface INetworkConfigurationService + { + /// + /// 创建网络配置 + /// + /// 配置键值 + /// RAN配置文件路径 + /// 核心网和IMS配置列表 + /// APN配置 + /// 频段配置 + /// 配置说明 + /// 创建的网络配置 + Task CreateAsync( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null); + + /// + /// 保存网络配置 + /// + /// 网络配置 + Task SaveAsync(NetworkConfiguration configuration); + + /// + /// 删除网络配置 + /// + /// 配置键值 + Task DeleteAsync(string configKey); + + /// + /// 获取所有网络配置 + /// + /// 网络配置列表 + Task> GetAllAsync(); + + /// + /// 根据配置键获取网络配置 + /// + /// 配置键值 + /// 网络配置 + Task GetByConfigKeyAsync(string configKey); + } +} \ No newline at end of file diff --git a/CoreAgent.Application/Queries/NetworkConfig/GetNetworkConfigurationQuery.cs b/CoreAgent.Application/Queries/NetworkConfig/GetNetworkConfigurationQuery.cs new file mode 100644 index 0000000..8a86275 --- /dev/null +++ b/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 +{ + /// + /// 获取所有网络配置查询 + /// + public class GetAllNetworkConfigurationsQuery : IRequest> + { + } + + /// + /// 根据配置键获取网络配置查询 + /// + public class GetNetworkConfigurationByKeyQuery : IRequest + { + /// + /// 配置键值 + /// + public string ConfigKey { get; set; } + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Contexts/CellularNetworkContext.cs b/CoreAgent.Domain/Contexts/CellularNetworkContext.cs index f0a3eb2..587992f 100644 --- a/CoreAgent.Domain/Contexts/CellularNetworkContext.cs +++ b/CoreAgent.Domain/Contexts/CellularNetworkContext.cs @@ -13,7 +13,8 @@ public class CellularNetworkContext private readonly object _lock = new(); private readonly Dictionary _networkStates = new(); private NetworkCommandConfig _networkCommandConfig; - + private string NeConfigKey; + public CancellationTokenSource token =new CancellationTokenSource(); /// /// 获取单例实例 /// @@ -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; + } + } /// /// 获取指定类型的命令配置 /// @@ -73,16 +89,16 @@ public class CellularNetworkContext /// /// 获取或创建网络状态 /// - /// 网络接口名称 + /// 网络接口名称 /// 网络状态 - public CellularNetworkState GetOrCreateNetworkState(string interfaceName) + public CellularNetworkState GetOrCreateNetworkState(string NeConfigKey) { lock (_lock) { - if (!_networkStates.TryGetValue(interfaceName, out var state)) + if (!_networkStates.TryGetValue(NeConfigKey, out var state)) { - state = new CellularNetworkState(interfaceName); - _networkStates[interfaceName] = state; + state = new CellularNetworkState(NeConfigKey); + _networkStates[NeConfigKey] = state; } return state; } @@ -91,12 +107,12 @@ public class CellularNetworkContext /// /// 移除网络状态 /// - /// 网络接口名称 - public void RemoveNetworkState(string interfaceName) + /// 网络接口名称 + public void RemoveNetworkState(string NeConfigKey) { lock (_lock) { - _networkStates.Remove(interfaceName); + _networkStates.Remove(NeConfigKey); } } @@ -121,7 +137,7 @@ public class CellularNetworkState /// /// 网络接口名称 /// - public string InterfaceName { get; } + public string NeConfigKey { get; } /// /// 是否已初始化 @@ -143,34 +159,18 @@ public class CellularNetworkState /// public NetworkStatus CurrentStatus { get; private set; } - /// - /// 当前信号强度 - /// - public SignalStrength CurrentSignalStrength { get; private set; } - /// /// 当前网络类型 /// public NetworkType CurrentNetworkType { get; private set; } - /// - /// 当前发射功率 - /// - public int CurrentTransmitPower { get; private set; } - /// - /// 网络配置 - /// - public CellularNetworkConfig Config { get; private set; } - public CellularNetworkState(string interfaceName) + public CellularNetworkState(string _NeConfigKey) { - InterfaceName = interfaceName; + NeConfigKey = _NeConfigKey; IsInitialized = false; CurrentStatus = NetworkStatus.Unknown; - CurrentSignalStrength = SignalStrength.NoSignal; - CurrentNetworkType = NetworkType.Unknown; - CurrentTransmitPower = 0; } /// @@ -181,13 +181,6 @@ public class CellularNetworkState CurrentStatus = status; } - /// - /// 更新信号强度 - /// - public void UpdateSignalStrength(SignalStrength strength) - { - CurrentSignalStrength = strength; - } /// /// 更新网络类型 @@ -197,21 +190,6 @@ public class CellularNetworkState CurrentNetworkType = type; } - /// - /// 更新发射功率 - /// - public void UpdateTransmitPower(int power) - { - CurrentTransmitPower = power; - } - - /// - /// 更新网络配置 - /// - public void UpdateConfig(CellularNetworkConfig config) - { - Config = config; - } /// /// 标记为已启动 @@ -231,8 +209,6 @@ public class CellularNetworkState IsInitialized = false; LastStopTime = DateTime.Now; CurrentStatus = NetworkStatus.Disconnected; - CurrentSignalStrength = SignalStrength.NoSignal; CurrentNetworkType = NetworkType.Unknown; - CurrentTransmitPower = 0; } } \ No newline at end of file diff --git a/CoreAgent.Domain/Entities/NetworkConfiguration.cs b/CoreAgent.Domain/Entities/NetworkConfiguration.cs index 1731b0a..e68be2d 100644 --- a/CoreAgent.Domain/Entities/NetworkConfiguration.cs +++ b/CoreAgent.Domain/Entities/NetworkConfiguration.cs @@ -2,11 +2,12 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Text.Json.Serialization; namespace CoreAgent.Domain.Entities { /// - /// 网络配置实体 + /// 网络配置聚合根 /// public class NetworkConfiguration : IValidatableObject { @@ -14,25 +15,27 @@ namespace CoreAgent.Domain.Entities /// 配置键值 /// [Required(ErrorMessage = "配置键值不能为空")] + [JsonPropertyName("configKey")] public string ConfigKey { get; set; } /// /// RAN配置文件路径 /// [Required(ErrorMessage = "RAN配置路径不能为空")] + [JsonPropertyName("ragConfig")] public string RagConfig { get; set; } /// /// 核心网和IMS配置列表 /// - [Required(ErrorMessage = "核心网和IMS配置不能为空")] - [MinLength(1, ErrorMessage = "至少需要一个核心网和IMS配置")] + [JsonPropertyName("coreOrImsConfigs")] public List CoreOrImsConfigs { get; set; } /// /// APN配置 /// [Required(ErrorMessage = "APN配置不能为空")] + [JsonPropertyName("apn")] public string Apn { get; set; } /// @@ -40,13 +43,55 @@ namespace CoreAgent.Domain.Entities /// [Required(ErrorMessage = "频段配置不能为空")] [MinLength(1, ErrorMessage = "至少需要一个频段配置")] + [JsonPropertyName("band")] public List Band { get; set; } /// /// 配置说明 /// + [JsonPropertyName("comment")] public string Comment { get; set; } + /// + /// 构造函数 + /// + [JsonConstructor] + public NetworkConfiguration() + { + CoreOrImsConfigs = new List(); + Band = new List(); + } + + /// + /// 创建新的网络配置 + /// + public static NetworkConfiguration Create( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null) + { + var config = new NetworkConfiguration + { + ConfigKey = configKey, + RagConfig = ragConfig, + Apn = apn, + Comment = comment, + CoreOrImsConfigs = coreOrImsConfigs ?? new List(), + Band = band ?? new List() + }; + + var validationResults = new List(); + if (!Validator.TryValidateObject(config, new ValidationContext(config), validationResults, true)) + { + throw new ValidationException(string.Join(Environment.NewLine, validationResults.Select(r => r.ErrorMessage))); + } + + return config; + } + /// /// 验证配置 /// @@ -97,31 +142,18 @@ namespace CoreAgent.Domain.Entities { return CoreOrImsConfigs.FirstOrDefault(x => x.Index == index); } + } + /// + /// 网络配置包装类 + /// + public class NetworkConfigurationsWrapper + { /// - /// 验证配置文件是否存在 + /// 网络配置列表 /// - public bool ValidateConfigFiles() - { - if (!System.IO.File.Exists(RagConfig)) - { - throw new InvalidOperationException($"RAN配置文件不存在: {RagConfig}"); - } - - foreach (var config in CoreOrImsConfigs) - { - if (!System.IO.File.Exists(config.CoreNetworkConfig)) - { - throw new InvalidOperationException($"核心网配置文件不存在: {config.CoreNetworkConfig}"); - } - if (!System.IO.File.Exists(config.ImsConfig)) - { - throw new InvalidOperationException($"IMS配置文件不存在: {config.ImsConfig}"); - } - } - - return true; - } + [JsonPropertyName("networkConfigurations")] + public List NetworkConfigurations { get; set; } = new List(); } /// @@ -134,6 +166,7 @@ namespace CoreAgent.Domain.Entities /// [Required(ErrorMessage = "配置索引不能为空")] [Range(1, int.MaxValue, ErrorMessage = "配置索引必须大于0")] + [JsonPropertyName("index")] public int Index { get; set; } /// @@ -141,6 +174,7 @@ namespace CoreAgent.Domain.Entities /// [Required(ErrorMessage = "PLMN码不能为空")] [RegularExpression(@"^\d{5,6}$", ErrorMessage = "PLMN码必须是5-6位数字")] + [JsonPropertyName("plmn")] public string Plmn { get; set; } /// @@ -148,6 +182,7 @@ namespace CoreAgent.Domain.Entities /// [Required(ErrorMessage = "核心网配置路径不能为空")] [RegularExpression(@"^Config/CoreNetwork/.*\.cfg$", ErrorMessage = "核心网配置路径格式不正确")] + [JsonPropertyName("coreNetworkConfig")] public string CoreNetworkConfig { get; set; } /// @@ -155,22 +190,7 @@ namespace CoreAgent.Domain.Entities /// [Required(ErrorMessage = "IMS配置路径不能为空")] [RegularExpression(@"^Config/Ims/.*\.cfg$", ErrorMessage = "IMS配置路径格式不正确")] + [JsonPropertyName("imsConfig")] public string ImsConfig { get; set; } - - /// - /// 获取配置文件的完整路径 - /// - public string GetFullCoreNetworkConfigPath() - { - return System.IO.Path.GetFullPath(CoreNetworkConfig); - } - - /// - /// 获取IMS配置文件的完整路径 - /// - public string GetFullImsConfigPath() - { - return System.IO.Path.GetFullPath(ImsConfig); - } } } \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/INetworkConfigurationRepository.cs b/CoreAgent.Domain/Interfaces/INetworkConfigurationRepository.cs new file mode 100644 index 0000000..5eca0e1 --- /dev/null +++ b/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 +{ + /// + /// 网络配置仓储接口 + /// + public interface INetworkConfigurationRepository + { + /// + /// 创建网络配置 + /// + /// 配置键值 + /// RAN配置文件路径 + /// 核心网和IMS配置列表 + /// APN配置 + /// 频段配置 + /// 配置说明 + /// 创建的网络配置 + Task CreateAsync( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null); + + /// + /// 保存网络配置 + /// + /// 网络配置 + Task SaveAsync(NetworkConfiguration configuration); + + /// + /// 删除网络配置 + /// + /// 配置键值 + Task DeleteAsync(string configKey); + + /// + /// 获取所有网络配置 + /// + /// 网络配置列表 + Task> GetAllAsync(); + + /// + /// 根据配置键获取网络配置 + /// + /// 配置键值 + /// 网络配置 + Task GetByConfigKeyAsync(string configKey); + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/INetworkConfigurationService.cs b/CoreAgent.Domain/Interfaces/INetworkConfigurationService.cs new file mode 100644 index 0000000..20147b1 --- /dev/null +++ b/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 +{ + /// + /// 网络配置服务接口 + /// + public interface INetworkConfigurationService + { + /// + /// 创建网络配置 + /// + /// 配置键值 + /// RAN配置文件路径 + /// 核心网和IMS配置列表 + /// APN配置 + /// 频段配置 + /// 配置说明 + /// 创建的网络配置 + Task CreateAsync( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null); + + /// + /// 保存网络配置 + /// + /// 网络配置 + Task SaveAsync(NetworkConfiguration configuration); + + /// + /// 删除网络配置 + /// + /// 配置键值 + Task DeleteAsync(string configKey); + + /// + /// 获取所有网络配置 + /// + /// 网络配置列表 + Task> GetAllAsync(); + + /// + /// 根据配置键获取网络配置 + /// + /// 配置键值 + /// 网络配置 + Task GetByConfigKeyAsync(string configKey); + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs b/CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs index a75754a..d077b83 100644 --- a/CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs +++ b/CoreAgent.Domain/Interfaces/Network/ICellularNetworkService.cs @@ -10,17 +10,15 @@ public interface ICellularNetworkService /// /// 启动蜂窝网络 /// - /// 网络接口名称 - /// 网络配置 + /// 网络配置映射Key /// 启动结果 - Task StartAsync(string interfaceName, CellularNetworkConfig config); + Task StartAsync(string Key); /// /// 停止蜂窝网络 /// - /// 网络接口名称 /// 停止结果 - Task StopAsync(string interfaceName); + Task StopAsync(); } /// @@ -81,24 +79,19 @@ public enum NetworkType Unknown, /// - /// 2G网络 - /// - G2, - - /// - /// 3G网络 + /// 4G网络 /// - G3, + LTE, /// - /// 4G网络 + /// 5G网络 /// - G4, + NR, /// - /// 5G网络 + /// 4+5 G网络 /// - G5 + LTE_NR, } /// diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkConfigurator.cs b/CoreAgent.Domain/Interfaces/Network/INetworkConfigurator.cs deleted file mode 100644 index 0313dd8..0000000 --- a/CoreAgent.Domain/Interfaces/Network/INetworkConfigurator.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CoreAgent.Domain.Models.Network; - -namespace CoreAgent.Domain.Interfaces.Network; - -/// -/// 网络配置器接口 -/// -public interface INetworkConfigurator -{ - /// - /// 配置网络参数 - /// - /// 网络接口名称 - /// 网络配置 - /// 配置结果 - Task ConfigureAsync(string interfaceName, CellularNetworkConfig config); - - /// - /// 设置发射功率 - /// - /// 网络接口名称 - /// 功率等级(0-100) - /// 设置结果 - Task SetTransmitPowerAsync(string interfaceName, int powerLevel); -} \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkStatusProvider.cs b/CoreAgent.Domain/Interfaces/Network/INetworkStatusProvider.cs deleted file mode 100644 index 8c03289..0000000 --- a/CoreAgent.Domain/Interfaces/Network/INetworkStatusProvider.cs +++ /dev/null @@ -1,36 +0,0 @@ -using CoreAgent.Domain.Models.Network; - -namespace CoreAgent.Domain.Interfaces.Network; - -/// -/// 网络状态提供者接口 -/// -public interface INetworkStatusProvider -{ - /// - /// 获取网络状态 - /// - /// 网络接口名称 - /// 网络状态信息 - Task GetNetworkStatusAsync(string interfaceName); - - /// - /// 获取信号强度 - /// - /// 网络接口名称 - /// 信号强度信息 - Task GetSignalStrengthAsync(string interfaceName); - - /// - /// 获取网络类型 - /// - /// 网络接口名称 - /// 网络类型信息 - Task GetNetworkTypeAsync(string interfaceName); - - /// - /// 获取全局状态 - /// - /// 全局状态信息 - Task GetGlobalStatusAsync(); -} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/System/CommandTemplateConfig.cs b/CoreAgent.Domain/Models/System/CommandTemplateConfig.cs index 0b4d850..38c3ca4 100644 --- a/CoreAgent.Domain/Models/System/CommandTemplateConfig.cs +++ b/CoreAgent.Domain/Models/System/CommandTemplateConfig.cs @@ -30,4 +30,28 @@ public class CommandTemplateConfig /// [JsonPropertyName("isEnabled")] public bool IsEnabled { get; set; } = true; + + /// + /// 是否需要返回结果 + /// + [JsonPropertyName("needReturnResult")] + public bool NeedReturnResult { get; set; } = false; + + /// + /// 是否需要后台执行 + /// + [JsonPropertyName("needBackgroundExecution")] + public bool NeedBackgroundExecution { get; set; } = false; + + /// + /// 命令是否可以被终止 + /// + [JsonPropertyName("canBeKilled")] + public bool CanBeKilled { get; set; } = false; + + /// + /// 是否需要带参数 + /// + [JsonPropertyName("hasParameters")] + public bool HasParameters { get; set; } = false; } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs index fadb9f7..3383a48 100644 --- a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs +++ b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs @@ -1,6 +1,9 @@ +using CoreAgent.Domain.Interfaces; using CoreAgent.Domain.Interfaces.Network; using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Infrastructure.Command.Factories; +using CoreAgent.Infrastructure.Repositories; +using CoreAgent.Infrastructure.Services; using CoreAgent.Infrastructure.Services.Network; using Microsoft.Extensions.DependencyInjection; @@ -27,12 +30,10 @@ public static class CommandServiceExtensions var factory = sp.GetRequiredService(); return factory.CreateExecutor(); }); - // 注册网络配置器 - services.AddScoped(); - - // 注册网络状态提供者 - services.AddScoped(); + services.AddScoped(); + // 注册网络配置器 + services.AddScoped(); // 注册网络服务 services.AddScoped(); diff --git a/CoreAgent.Infrastructure/Repositories/NetworkConfigurationRepository.cs b/CoreAgent.Infrastructure/Repositories/NetworkConfigurationRepository.cs new file mode 100644 index 0000000..60d06f8 --- /dev/null +++ b/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 +{ + /// + /// 网络配置仓储实现 + /// + 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 + }; + + /// + /// 构造函数 + /// + /// 配置 + 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); + } + } + + /// + /// 创建网络配置 + /// + public async Task CreateAsync( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null) + { + var config = NetworkConfiguration.Create( + configKey, + ragConfig, + coreOrImsConfigs, + apn, + band, + comment + ); + + await SaveAsync(config); + return config; + } + + /// + /// 保存网络配置 + /// + 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); + } + + /// + /// 删除网络配置 + /// + 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); + } + } + + /// + /// 获取所有网络配置 + /// + public async Task> GetAllAsync() + { + if (!File.Exists(_configFilePath)) + { + return new List(); + } + + var json = await File.ReadAllTextAsync(_configFilePath); + try + { + // 验证JSON格式 + using (JsonDocument.Parse(json)) + { + // JSON格式正确 + } + + var result = JsonSerializer.Deserialize(json, _jsonOptions); + if (result == null) + { + throw new JsonException("反序列化结果为null"); + } + return result.NetworkConfigurations ?? new List(); + } + catch (JsonException ex) + { + throw new InvalidOperationException($"JSON反序列化失败: {ex.Message}", ex); + } + } + + /// + /// 根据配置键获取网络配置 + /// + public async Task GetByConfigKeyAsync(string configKey) + { + if (string.IsNullOrEmpty(configKey)) + { + throw new ArgumentException("配置键值不能为空", nameof(configKey)); + } + + var configs = await GetAllAsync(); + return configs.FirstOrDefault(c => c.ConfigKey == configKey); + } + + /// + /// 保存配置列表 + /// + private async Task SaveConfigurationsAsync(List configurations) + { + if (configurations == null) + { + throw new ArgumentNullException(nameof(configurations)); + } + + var json = JsonSerializer.Serialize(new { networkConfigurations = configurations }, _jsonOptions); + await File.WriteAllTextAsync(_configFilePath, json); + } + } +} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkConfigurator.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkConfigurator.cs deleted file mode 100644 index f9bb384..0000000 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkConfigurator.cs +++ /dev/null @@ -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; - -/// -/// 蜂窝网络配置器实现 -/// -public class CellularNetworkConfigurator : INetworkConfigurator -{ - private readonly ILogger _logger; - private readonly ISystemCommandExecutor _commandExecutor; - - public CellularNetworkConfigurator( - ILogger logger, - ISystemCommandExecutor commandExecutor) - { - _logger = logger; - _commandExecutor = commandExecutor; - } - - public async Task 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 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 ExecuteCommandAsync(string command) - { - var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); - return result.IsSuccess; - } -} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs index 605ceb8..dd9eed3 100644 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs +++ b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs @@ -1,4 +1,7 @@ +using CliWrap; using CoreAgent.Domain.Contexts; +using CoreAgent.Domain.Entities; +using CoreAgent.Domain.Interfaces; using CoreAgent.Domain.Interfaces.Network; using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Domain.Models.Network; @@ -14,27 +17,36 @@ public class CellularNetworkService : ICellularNetworkService { private readonly ILogger _logger; private readonly ISystemCommandExecutor _commandExecutor; - private readonly INetworkConfigurator _configurator; + private readonly INetworkConfigurationService _configService; private readonly CellularNetworkContext _context; 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( ILogger logger, ISystemCommandExecutor commandExecutor, - INetworkConfigurator configurator) + INetworkConfigurationService configService) { - _logger = logger; - _commandExecutor = commandExecutor; - _configurator = configurator; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor)); + _configService = configService ?? throw new ArgumentNullException(nameof(configService)); _context = CellularNetworkContext.Instance; } - public async Task StartAsync(string interfaceName, CellularNetworkConfig config) + public async Task StartAsync(string key) { + if (string.IsNullOrEmpty(key)) + { + _logger.LogError("启动蜂窝网络失败:配置键为空"); + return false; + } + try { - // 使用信号量确保只能启动一次 - if (!await _startLock.WaitAsync(TimeSpan.FromSeconds(5))) + if (!await _startLock.WaitAsync(TimeSpan.FromSeconds(LockTimeoutSeconds))) { _logger.LogWarning("蜂窝网络启动操作被锁定,可能已有其他启动操作正在进行"); return false; @@ -42,47 +54,7 @@ public class CellularNetworkService : ICellularNetworkService try { - var commands = _context.GetNetworkCommandConfig(); - - var state = _context.GetOrCreateNetworkState(interfaceName); - if (state.IsInitialized) - { - _logger.LogWarning("蜂窝网络已经初始化,不能重复启动"); - return false; - } - - _logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", interfaceName); - - // 1. 配置网络参数 - var configResult = await _configurator.ConfigureAsync(interfaceName, config); - if (!configResult) - { - _logger.LogError("配置蜂窝网络参数失败"); - return false; - } - - // 2. 启动网络接口 - var startResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" admin=enable"); - if (!startResult) - { - _logger.LogError("启动蜂窝网络接口失败"); - return false; - } - - // 3. 等待网络连接 - var connected = await WaitForConnectionAsync(interfaceName); - if (!connected) - { - _logger.LogError("蜂窝网络连接超时"); - return false; - } - - // 4. 更新状态 - state.UpdateConfig(config); - state.MarkAsStarted(); - - _logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", interfaceName); - return true; + return await StartInternalAsync(key); } finally { @@ -91,72 +63,329 @@ public class CellularNetworkService : ICellularNetworkService } catch (Exception ex) { - _logger.LogError(ex, "启动蜂窝网络接口 {InterfaceName} 失败", interfaceName); + _logger.LogError(ex, "启动蜂窝网络接口失败"); return false; } } - public async Task StopAsync(string interfaceName) + + public async Task StopAsync() { + string NeConfigKey = _context.GetNeConfigKey(); try { - var state = _context.GetOrCreateNetworkState(interfaceName); + + // 1. 检查网络状态 + var state = _context.GetOrCreateNetworkState(NeConfigKey); if (!state.IsInitialized) { _logger.LogWarning("蜂窝网络未初始化,无需停止"); return true; } - _logger.LogInformation("正在停止蜂窝网络接口: {InterfaceName}", interfaceName); + // 2. 执行初始化命令 + await ExecuteInitializeCommandsAsync(); + + // 3. 执行停止命令 + _logger.LogInformation("正在执行停止命令: {InterfaceName}", NeConfigKey); + var commands = _context.GetNetworkCommandConfig(); + if (commands?.NetworkCommands != null) + { + var stopCommands = commands.NetworkCommands + .Where(s => s.Type == NetworkCommandType.Stop) + .ToArray(); + + foreach (var cmd in stopCommands) + { + if (!await ExecuteCommandAsync(cmd)) + { + _logger.LogWarning("停止命令执行失败: {Template}", cmd.Template); + } + } + } - // 1. 停止网络接口 - var stopResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" admin=disable"); - if (!stopResult) + // 4. 停止网络接口 + if (!await DisableNetworkInterfaceAsync(NeConfigKey)) { - _logger.LogError("停止蜂窝网络接口失败"); return false; } - // 2. 更新状态 + // 5. 更新状态 state.MarkAsStopped(); - - _logger.LogInformation("蜂窝网络接口 {InterfaceName} 停止成功", interfaceName); + _logger.LogInformation($"蜂窝网络 {NeConfigKey} 停止成功"); return true; } catch (Exception ex) { - _logger.LogError(ex, "停止蜂窝网络接口 {InterfaceName} 失败", interfaceName); + _logger.LogError(ex, $"停止蜂窝网络 {NeConfigKey} 失败"); return false; } } - private async Task WaitForConnectionAsync(string interfaceName) + private async Task StartInternalAsync(string key) { - const int maxAttempts = 30; - const int delayMs = 1000; + // 1. 获取并验证配置 + var config = await _configService.GetByConfigKeyAsync(key); + if (config == null) + { + _logger.LogError("未找到网络配置: {ConfigKey}", key); + return false; + } - for (int i = 0; i < maxAttempts; i++) + // 2. 检查网络状态 + var state = _context.GetOrCreateNetworkState(DefaultInterfaceName); + if (state.IsInitialized) { - var status = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\""); - if (status.IsSuccess && status.Output.Contains("已连接", StringComparison.OrdinalIgnoreCase)) + _logger.LogWarning("蜂窝网络已经初始化,不能重复启动"); + return false; + } + + // 3. 执行初始化命令 + await ExecuteInitializeCommandsAsync(); + + // 4. 启动网络接口 + _logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", DefaultInterfaceName); + if (!await EnableNetworkInterfaceAsync(config)) + { + return false; + } + + // 5. 等待连接 + if (!await WaitForConnectionAsync(DefaultInterfaceName)) + { + return false; + } + + // 6. 更新状态 + state.MarkAsStarted(); + _logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", DefaultInterfaceName); + return true; + } + + private async Task ExecuteInitializeCommandsAsync() + { + + var commands = _context.GetNetworkCommandConfig(); + if (commands?.NetworkCommands != null) + { + var initCommands = commands.NetworkCommands + .Where(s => s.Type == NetworkCommandType.Initialize) + .ToArray(); + + foreach (var cmd in initCommands) { - return true; + if (!await ExecuteCommandAsync(cmd)) + { + _logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template); + } } + } + } - await Task.Delay(delayMs); + private async Task 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) + { + _logger.LogError(ex, "执行命令失败: {Template}", command.Template); + return false; } + } - return false; + 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 EnableNetworkInterfaceAsync(NetworkConfiguration networkConfig) + { + try + { + var commands = _context.GetNetworkCommandConfig(); + var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.Start); + if (startCommand == null) + { + _logger.LogError("未找到启动命令配置"); + return false; + } + + // 根据配置类型执行不同的启动命令 + 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); + } + + _logger.LogWarning("无有效配置,跳过启动"); + return false; + } + catch (Exception ex) + { + _logger.LogError(ex, "启动网络接口失败"); + return false; + } + } + + private bool HasBothRagAndCoreConfigs(NetworkConfiguration config) + { + return !string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any(); + } + + private bool HasOnlyRagConfig(NetworkConfiguration config) + { + return !string.IsNullOrWhiteSpace(config.RagConfig) && !config.CoreOrImsConfigs.Any(); + } + + private bool HasOnlyCoreConfigs(NetworkConfiguration config) + { + return string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any(); + } + + private async Task ExecuteFullConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) + { + if (networkConfig.CoreOrImsConfigs.Count == 1) + { + return await ExecuteSingleConfigStartCommandAsync(startCommand, networkConfig); + } + return await ExecuteMultiConfigStartCommandsAsync(startCommand, networkConfig); + } + + private async Task ExecuteRagOnlyStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) + { + var command = string.Format(startCommand.Template, 1); + var fullCommand = $"{command} {networkConfig.RagConfig}"; + + _logger.LogInformation("执行RAG配置启动命令: {Command}", fullCommand); + var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.token); + return result.IsSuccess; + } + + private async Task ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) + { + var commands = new List(); + 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; } - private async Task ExecuteCommandAsync(string command) + private async Task ExecuteSingleConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) { - var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); + 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 ExecuteCommandWithResultAsync(string command) + private async Task ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) { - return await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); + var commands = new List(); + + // 添加主配置命令 + 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 true; + } + + private async Task DisableNetworkInterfaceAsync(string interfaceName) + { + var result = await _commandExecutor.ExecuteCommandAsync( + $"netsh interface cellular set interface \"{interfaceName}\" admin=disable", + new CancellationTokenSource()); + + if (!result.IsSuccess) + { + _logger.LogError("停止蜂窝网络接口失败"); + return false; + } + return true; + } + + private async Task WaitForConnectionAsync(string interfaceName) + { + 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; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkStatusProvider.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkStatusProvider.cs deleted file mode 100644 index fe01a5e..0000000 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkStatusProvider.cs +++ /dev/null @@ -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; - -/// -/// 蜂窝网络状态提供者实现 -/// -public class CellularNetworkStatusProvider : INetworkStatusProvider -{ - private readonly ILogger _logger; - private readonly ISystemCommandExecutor _commandExecutor; - private readonly CellularNetworkContext _context; - - public CellularNetworkStatusProvider( - ILogger logger, - ISystemCommandExecutor commandExecutor) - { - _logger = logger; - _commandExecutor = commandExecutor; - _context = CellularNetworkContext.Instance; - } - - public async Task 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 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 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 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 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 ParseInterfaces(string output) - { - var interfaces = new List(); - 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; - } -} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/Extensions/ServiceCollectionExtensions.cs b/CoreAgent.Infrastructure/Services/Network/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..36e153a --- /dev/null +++ b/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(); + return services; + } +} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/NetworkConfigurationService.cs b/CoreAgent.Infrastructure/Services/NetworkConfigurationService.cs new file mode 100644 index 0000000..5ff66df --- /dev/null +++ b/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 +{ + /// + /// 网络配置服务实现 + /// + public class NetworkConfigurationService : INetworkConfigurationService + { + private readonly INetworkConfigurationRepository _repository; + + /// + /// 构造函数 + /// + /// 网络配置仓储 + public NetworkConfigurationService(INetworkConfigurationRepository repository) + { + _repository = repository; + } + + /// + /// 创建网络配置 + /// + public Task CreateAsync( + string configKey, + string ragConfig, + List coreOrImsConfigs, + string apn, + List band, + string comment = null) + { + return _repository.CreateAsync(configKey, ragConfig, coreOrImsConfigs, apn, band, comment); + } + + /// + /// 保存网络配置 + /// + public Task SaveAsync(NetworkConfiguration configuration) + { + return _repository.SaveAsync(configuration); + } + + /// + /// 删除网络配置 + /// + public Task DeleteAsync(string configKey) + { + return _repository.DeleteAsync(configKey); + } + + /// + /// 获取所有网络配置 + /// + public Task> GetAllAsync() + { + return _repository.GetAllAsync(); + } + + /// + /// 根据配置键获取网络配置 + /// + public Task GetByConfigKeyAsync(string configKey) + { + return _repository.GetByConfigKeyAsync(configKey); + } + } +} \ No newline at end of file