diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs b/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs
new file mode 100644
index 0000000..196723b
--- /dev/null
+++ b/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs
@@ -0,0 +1,19 @@
+using CoreAgent.Domain.Entities;
+using CoreAgent.Domain.Models.Network;
+using CoreAgent.Domain.Models.System;
+
+namespace CoreAgent.Domain.Interfaces.Network;
+
+///
+/// 网络配置复制器接口
+///
+public interface INetworkConfigCopier
+{
+ ///
+ /// 将配置值复制到临时目录并更新配置路径
+ ///
+ /// 网络配置
+ /// 应用设置
+ /// 复制结果
+ Task CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig, AppSettings appSettings);
+}
\ No newline at end of file
diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkInterfaceManager.cs b/CoreAgent.Domain/Interfaces/Network/INetworkInterfaceManager.cs
new file mode 100644
index 0000000..1f53994
--- /dev/null
+++ b/CoreAgent.Domain/Interfaces/Network/INetworkInterfaceManager.cs
@@ -0,0 +1,31 @@
+using CoreAgent.Domain.Entities;
+using CoreAgent.Domain.Models.Network;
+
+namespace CoreAgent.Domain.Interfaces.Network;
+
+///
+/// 网络接口管理器接口
+///
+public interface INetworkInterfaceManager
+{
+ ///
+ /// 执行初始化命令
+ ///
+ /// 是否为启动时的初始化
+ /// 初始化结果
+ Task ExecuteInitializeCommandsAsync(bool isStartup = false);
+
+ ///
+ /// 启用网络接口
+ ///
+ /// 网络配置
+ /// 启用结果
+ Task EnableAsync(NetworkConfiguration networkConfig);
+
+ ///
+ /// 禁用网络接口
+ ///
+ /// 网络配置键
+ /// 禁用结果
+ Task DisableAsync(string neConfigKey);
+}
\ No newline at end of file
diff --git a/CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs b/CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs
new file mode 100644
index 0000000..f53eb26
--- /dev/null
+++ b/CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs
@@ -0,0 +1,34 @@
+namespace CoreAgent.Domain.Models.Network;
+
+///
+/// 网络配置复制结果
+///
+public class NetworkConfigCopyResult
+{
+ ///
+ /// 是否成功
+ ///
+ public bool IsSuccess { get; }
+
+ ///
+ /// 错误信息
+ ///
+ public string ErrorMessage { get; }
+
+ private NetworkConfigCopyResult(bool isSuccess, string errorMessage = null)
+ {
+ IsSuccess = isSuccess;
+ ErrorMessage = errorMessage;
+ }
+
+ ///
+ /// 创建成功结果
+ ///
+ public static NetworkConfigCopyResult Success() => new(true);
+
+ ///
+ /// 创建失败结果
+ ///
+ /// 错误信息
+ public static NetworkConfigCopyResult Failure(string errorMessage) => new(false, errorMessage);
+}
\ No newline at end of file
diff --git a/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs b/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs
new file mode 100644
index 0000000..ba4aeb2
--- /dev/null
+++ b/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs
@@ -0,0 +1,34 @@
+namespace CoreAgent.Domain.Models.Network;
+
+///
+/// 网络接口操作结果
+///
+public class NetworkInterfaceOperationResult
+{
+ ///
+ /// 是否成功
+ ///
+ public bool IsSuccess { get; }
+
+ ///
+ /// 错误信息
+ ///
+ public string ErrorMessage { get; }
+
+ private NetworkInterfaceOperationResult(bool isSuccess, string errorMessage = null)
+ {
+ IsSuccess = isSuccess;
+ ErrorMessage = errorMessage;
+ }
+
+ ///
+ /// 创建成功结果
+ ///
+ public static NetworkInterfaceOperationResult Success() => new(true);
+
+ ///
+ /// 创建失败结果
+ ///
+ /// 错误信息
+ public static NetworkInterfaceOperationResult Failure(string errorMessage) => new(false, errorMessage);
+}
\ No newline at end of file
diff --git a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
index 200bc4b..1b082df 100644
--- a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
+++ b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
@@ -36,7 +36,8 @@ public static class CommandServiceExtensions
services.AddScoped();
// 注册网络配置器
services.AddScoped();
-
+ services.AddScoped();
+ services.AddScoped();
// 注册网络服务
services.AddScoped();
diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs
index 8996b9a..79d1d21 100644
--- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs
+++ b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs
@@ -21,23 +21,30 @@ public class CellularNetworkService : ICellularNetworkService
private readonly ISystemCommandExecutor _commandExecutor;
private readonly INetworkConfigurationService _configService;
private readonly ICellularNetworkContext _context;
+ private readonly INetworkConfigCopier _configCopier;
+ private readonly INetworkInterfaceManager _interfaceManager;
private static readonly SemaphoreSlim _startLock = new(1, 1);
private const int MaxConnectionAttempts = 30;
private const int ConnectionCheckDelayMs = 1000;
private const int LockTimeoutSeconds = 5;
private const string NULL_CONFIG = "NULL";
private const string KILL_COMMAND_TEMPLATE = "ps -ef | grep {0} | grep -v grep | awk '{{print $2}}' | xargs kill -9";
+ private const string COM_ADDR_TEMPLATE = "cat {0} | grep com_addr | awk -F'\"' '{{print $4}}'";
public CellularNetworkService(
ILogger logger,
ISystemCommandExecutor commandExecutor,
INetworkConfigurationService configService,
- ICellularNetworkContext context)
+ ICellularNetworkContext context,
+ INetworkConfigCopier configCopier,
+ INetworkInterfaceManager interfaceManager)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
_configService = configService ?? throw new ArgumentNullException(nameof(configService));
_context = context ?? throw new ArgumentNullException(nameof(context));
+ _configCopier = configCopier ?? throw new ArgumentNullException(nameof(configCopier));
+ _interfaceManager = interfaceManager ?? throw new ArgumentNullException(nameof(interfaceManager));
}
///
@@ -163,30 +170,16 @@ public class CellularNetworkService : ICellularNetworkService
}
// 2. 执行初始化命令
- await ExecuteInitializeCommandsAsync();
-
- // 3. 执行停止命令
- _logger.LogInformation("正在执行停止命令: {ConfigKey}", neConfigKey);
- var commands = _context.GetNetworkCommandConfig();
- if (commands?.NetworkCommands != null)
+ var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync();
+ if (!initResult.IsSuccess)
{
- var stopCommands = commands.NetworkCommands
- .Where(s => s.Type == NetworkCommandType.StopNetwork)
- .ToArray();
-
- foreach (var cmd in stopCommands)
- {
- if (!await ExecuteCommandAsync(cmd))
- {
- _logger.LogWarning("停止命令执行失败: {Template}", cmd.Template);
- }
- }
+ _logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage);
}
-
// 4. 停止网络配置
- if (!await DisableNetworkInterfaceAsync(neConfigKey))
+ var disableResult = await _interfaceManager.DisableAsync(neConfigKey);
+ if (!disableResult.IsSuccess)
{
- return CellularNetworkOperationResult.Failure("停止网络配置失败");
+ return CellularNetworkOperationResult.Failure(disableResult.ErrorMessage);
}
// 5. 更新状态
@@ -215,414 +208,35 @@ public class CellularNetworkService : ICellularNetworkService
}
// 2. 执行初始化命令
- await ExecuteInitializeCommandsAsync(true);
+ var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync(true);
+ if (!initResult.IsSuccess)
+ {
+ _logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage);
+ }
- // 3. 启动网络配置
+ // 3. 复制配置值到临时目录并更新配置路径
+ var copyResult = await _configCopier.CopyConfigValuesToTempAsync(config, _context.GetAppSettings());
+ if (!copyResult.IsSuccess)
+ {
+ var message = $"复制配置值到临时目录失败: {copyResult.ErrorMessage}";
+ _logger.LogError(message);
+ return CellularNetworkOperationResult.Failure(message);
+ }
+
+ // 4. 启动网络配置
_logger.LogInformation("正在启动蜂窝网络配置: {ConfigKey}", key);
- if (!await EnableNetworkInterfaceAsync(config))
+ var enableResult = await _interfaceManager.EnableAsync(config);
+ if (!enableResult.IsSuccess)
{
- var message = $"启动网络配置失败: {key}";
+ var message = $"启动网络配置失败: {enableResult.ErrorMessage}";
_logger.LogError(message);
return CellularNetworkOperationResult.Failure(message);
}
- // 4. 更新状态
+ // 5. 更新状态
var state = _context.GetNetworkState();
state.MarkAsStarted();
_logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功", key);
return CellularNetworkOperationResult.Success(state.CurrentStatus);
}
-
- private async Task ExecuteInitializeCommandsAsync(bool bStartInit = false)
- {
- var commands = _context.GetNetworkCommandConfig();
- if (commands?.NetworkCommands != null)
- {
- var initCommands = commands.NetworkCommands
- .Where(s => s.Type == NetworkCommandType.Initialize ||
- (bStartInit && s.Type == NetworkCommandType.PreNetworkOperation))
- .ToArray();
-
- foreach (var cmd in initCommands)
- {
- if (!await ExecuteCommandAsync(cmd))
- {
- _logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template);
- }
- }
- }
- }
-
- private async Task ExecuteCommandAsync(CommandTemplateConfig command)
- {
- try
- {
- if (command.CanBeKilled)
- {
- return await KillProcessAsync(command.Template, command.Timeout);
- }
-
- var result = await _commandExecutor.ExecuteCommandAsync(command.Template, new CancellationTokenSource(),command.Timeout);
- return result.IsSuccess;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "执行命令失败: {Template}", command.Template);
- return false;
- }
- }
-
- private async Task KillProcessAsync(string template,int Timeout)
- {
- string killCmd = string.Format(KILL_COMMAND_TEMPLATE, template);
- var result = await _commandExecutor.ExecuteCommandAsync(killCmd, new CancellationTokenSource());
- _logger.LogInformation("已终止进程: {Template}", template);
- return result.IsSuccess;
- }
-
- private async Task EnableNetworkInterfaceAsync(NetworkConfiguration networkConfig)
- {
- try
- {
- // 验证配置
- if (!ValidateConfig(networkConfig))
- {
- _logger.LogError("网络配置验证失败");
- return false;
- }
-
- // 复制配置值到临时目录并更新配置路径
- if (!CopyConfigValuesToTempAsync(networkConfig))
- {
- _logger.LogError("复制配置值到临时目录失败");
- return false;
- }
-
- var commands = _context.GetNetworkCommandConfig();
- var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.NetworkOperation);
- 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 CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig)
- {
- try
- {
- // 确保所需目录存在
- EnsureDirectoriesExist();
-
- // 复制 RAG 配置文件
- if (!string.IsNullOrEmpty(networkConfig.RagConfig))
- {
- if (!CopyConfigFile(networkConfig.RagConfig, _context.GetAppSettings().RanConfigDirectory,
- path => networkConfig.RagConfig = path, "RAG"))
- {
- return false;
- }
- }
-
- // 复制核心网络配置文件和IMS配置文件
- foreach (var config in networkConfig.CoreOrImsConfigs)
- {
- if (!string.IsNullOrEmpty(config.CoreNetworkConfig))
- {
- if (!CopyConfigFile(config.CoreNetworkConfig, _context.GetAppSettings().MmeConfigDirectory,
- path => config.CoreNetworkConfig = path, "核心网络"))
- {
- return false;
- }
- }
-
- if (!string.IsNullOrEmpty(config.ImsConfig))
- {
- if (!CopyConfigFile(config.ImsConfig, _context.GetAppSettings().MmeConfigDirectory,
- path => config.ImsConfig = path, "IMS"))
- {
- return false;
- }
- }
- }
-
- return true;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "复制配置文件到临时目录时发生错误");
- return false;
- }
- }
-
- private void EnsureDirectoriesExist()
- {
- var appSettings = _context.GetAppSettings();
- if (!Directory.Exists(appSettings.TempDirectory))
- {
- Directory.CreateDirectory(appSettings.TempDirectory);
- }
- if (!Directory.Exists(appSettings.RanConfigDirectory))
- {
- Directory.CreateDirectory(appSettings.RanConfigDirectory);
- }
- if (!Directory.Exists(appSettings.MmeConfigDirectory))
- {
- Directory.CreateDirectory(appSettings.MmeConfigDirectory);
- }
- }
-
- private bool CopyConfigFile(string sourcePath, string targetDirectory, Action updatePath, string configType)
- {
- var appSettings = _context.GetAppSettings();
- if (!File.Exists(sourcePath))
- {
- _logger.LogError("{ConfigType}配置文件不存在: {FilePath}", configType, sourcePath);
- return false;
- }
-
- var fileName = Path.GetFileName(sourcePath);
- var tempPath = Path.Combine(appSettings.TempDirectory, fileName);
-
- // 始终复制到临时目录
- File.Copy(sourcePath, tempPath, true);
-
- // 如果不在目标目录下,则复制到该目录并更新路径
- if (!sourcePath.StartsWith(targetDirectory))
- {
- var targetPath = Path.Combine(targetDirectory, fileName);
- File.Copy(sourcePath, targetPath, true);
- updatePath(targetPath);
- _logger.LogInformation("{ConfigType}配置文件已复制到目标目录: {FilePath}", configType, targetPath);
- }
- else
- {
- _logger.LogInformation("{ConfigType}配置文件已在目标目录中: {FilePath}", configType, sourcePath);
- }
-
- return true;
- }
-
- 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, new CancellationTokenSource());
- return result.IsSuccess;
- }
-
- private async Task ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
- {
- var commands = new List();
- var secondaryConfigs = networkConfig.CoreOrImsConfigs.ToArray();
-
- var secondaryTasks = new List>();
-
- for (int i = 0; i < secondaryConfigs.Length; i++)
- {
- var config = secondaryConfigs[i];
- var command = string.Format(startCommand.Template, i + 1);
- var fullCommand = $"{command} {NULL_CONFIG} {config.CoreNetworkConfig} {config.ImsConfig}";
-
- _logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
- secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
- }
- // 等待所有次要配置命令执行完成
- var secondaryResults = await Task.WhenAll(secondaryTasks);
- if (secondaryResults.Any(r => !r.IsSuccess))
- {
- _logger.LogWarning("部分次要配置命令执行失败");
- return false;
- }
- return true;
- }
-
- private async Task 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.TokenSource);
- return result.IsSuccess;
- }
-
- private async Task ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
- {
- var commands = new List();
-
- // 添加次要配置命令
- var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
- var secondaryTasks = new List>();
-
- for (int i = 0; i < secondaryConfigs.Length; i++)
- {
- var config = secondaryConfigs[i];
- var command = string.Format(startCommand.Template, i + 2);
- var fullCommand = $"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}";
-
- _logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
- secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
- }
-
- // 等待所有次要配置命令执行完成
- var secondaryResults = await Task.WhenAll(secondaryTasks);
- if (secondaryResults.Any(r => !r.IsSuccess))
- {
- _logger.LogWarning("部分次要配置命令执行失败");
- return false;
- }
-
- // 执行主配置命令
- var primaryConfig = networkConfig.CoreOrImsConfigs.FirstOrDefault(s => s.Index == 1);
- if (primaryConfig != null)
- {
- var primaryCommand = string.Format(startCommand.Template, 1);
- var fullCommand = $"{primaryCommand} {networkConfig.RagConfig} {primaryConfig.CoreNetworkConfig} {primaryConfig.ImsConfig}";
-
- _logger.LogInformation("执行主配置启动命令: {Command}", fullCommand);
- var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
- if (!result.IsSuccess)
- {
- _logger.LogWarning("主配置命令执行失败: {Command}", fullCommand);
- return false;
- }
- }
-
- return true;
- }
-
- private async Task DisableNetworkInterfaceAsync(string neConfigKey)
- {
- var result = await _commandExecutor.ExecuteCommandAsync(
- $"netsh interface cellular set interface \"{neConfigKey}\" admin=disable",
- new CancellationTokenSource());
-
- if (!result.IsSuccess)
- {
- _logger.LogError("停止网络配置失败");
- return false;
- }
- return true;
- }
-
- private async Task WaitForConnectionAsync(string neConfigKey)
- {
- for (int i = 0; i < MaxConnectionAttempts; i++)
- {
- var status = await _commandExecutor.ExecuteCommandAsync(
- $"netsh interface cellular show interfaces \"{neConfigKey}\"",
- new CancellationTokenSource());
-
- if (status.IsSuccess && status.Output.Contains("已连接", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
-
- await Task.Delay(ConnectionCheckDelayMs);
- }
-
- _logger.LogError("蜂窝网络连接超时");
- return false;
- }
-
- ///
- /// 验证网络配置是否有效
- ///
- private bool ValidateConfig(NetworkConfiguration config)
- {
- if (config == null)
- {
- _logger.LogError("网络配置为空");
- return false;
- }
-
- // 验证RAG配置
- if (!string.IsNullOrEmpty(config.RagConfig) && !File.Exists(config.RagConfig))
- {
- _logger.LogError("RAG配置文件不存在: {FilePath}", config.RagConfig);
- return false;
- }
-
- // 验证核心网络和IMS配置
- if (config.CoreOrImsConfigs != null)
- {
- foreach (var coreConfig in config.CoreOrImsConfigs)
- {
- if (!string.IsNullOrEmpty(coreConfig.CoreNetworkConfig) && !File.Exists(coreConfig.CoreNetworkConfig))
- {
- _logger.LogError("核心网络配置文件不存在: {FilePath}", coreConfig.CoreNetworkConfig);
- return false;
- }
-
- if (!string.IsNullOrEmpty(coreConfig.ImsConfig) && !File.Exists(coreConfig.ImsConfig))
- {
- _logger.LogError("IMS配置文件不存在: {FilePath}", coreConfig.ImsConfig);
- return false;
- }
- }
- }
-
- // 验证至少有一个有效配置
- if (string.IsNullOrEmpty(config.RagConfig) && (config.CoreOrImsConfigs == null || !config.CoreOrImsConfigs.Any()))
- {
- _logger.LogError("没有有效的网络配置");
- return false;
- }
-
- return true;
- }
}
\ No newline at end of file
diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs b/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
new file mode 100644
index 0000000..4f9342f
--- /dev/null
+++ b/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
@@ -0,0 +1,180 @@
+using CoreAgent.Domain.Entities;
+using CoreAgent.Domain.Interfaces;
+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 NetworkConfigCopier : INetworkConfigCopier
+{
+ private readonly ILogger _logger;
+ private readonly ISystemCommandExecutor _commandExecutor;
+ private const string COM_ADDR_TEMPLATE = "cat {0} | grep com_addr | awk -F'\"' '{{print $4}}'";
+
+ public NetworkConfigCopier(
+ ILogger logger,
+ ISystemCommandExecutor commandExecutor)
+ {
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
+ }
+
+ ///
+ /// 将配置值复制到临时目录并更新配置路径
+ ///
+ public async Task CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig, AppSettings appSettings)
+ {
+ try
+ {
+ // 确保所需目录存在
+ EnsureDirectoriesExist(appSettings);
+
+ // 复制 RAG 配置文件
+ if (!string.IsNullOrEmpty(networkConfig.RagConfig))
+ {
+ // 获取com_addr值
+ var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(networkConfig.RagConfig, "RAG");
+ if (!isSuccess)
+ {
+ return NetworkConfigCopyResult.Failure($"RAG配置文件验证失败: {errorMessage}");
+ }
+
+ if (!CopyConfigFile(networkConfig.RagConfig, appSettings.RanConfigDirectory,
+ path => networkConfig.RagConfig = path, "RAG"))
+ {
+ return NetworkConfigCopyResult.Failure("复制RAG配置文件失败");
+ }
+ }
+
+ // 复制核心网络配置文件和IMS配置文件
+ foreach (var config in networkConfig.CoreOrImsConfigs)
+ {
+ if (!string.IsNullOrEmpty(config.CoreNetworkConfig))
+ {
+ // 获取CN com_addr值
+ var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(config.CoreNetworkConfig, "CN");
+ if (!isSuccess)
+ {
+ return NetworkConfigCopyResult.Failure($"CN配置文件验证失败: {errorMessage}");
+ }
+
+ if (!CopyConfigFile(config.CoreNetworkConfig, appSettings.MmeConfigDirectory,
+ path => config.CoreNetworkConfig = path, "核心网络"))
+ {
+ return NetworkConfigCopyResult.Failure("复制CN配置文件失败");
+ }
+ }
+
+ if (!string.IsNullOrEmpty(config.ImsConfig))
+ {
+ // 获取IMS com_addr值
+ var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(config.ImsConfig, "IMS");
+ if (!isSuccess)
+ {
+ return NetworkConfigCopyResult.Failure($"IMS配置文件验证失败: {errorMessage}");
+ }
+
+ if (!CopyConfigFile(config.ImsConfig, appSettings.MmeConfigDirectory,
+ path => config.ImsConfig = path, "IMS"))
+ {
+ return NetworkConfigCopyResult.Failure("复制IMS配置文件失败");
+ }
+ }
+ }
+
+ return NetworkConfigCopyResult.Success();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "复制配置文件到临时目录时发生错误");
+ return NetworkConfigCopyResult.Failure($"复制配置文件时发生错误: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 获取配置文件中的com_addr值
+ ///
+ private async Task<(bool IsSuccess, string ComAddr, string ErrorMessage)> GetComAddrValueAsync(string configPath, string configType)
+ {
+ if (string.IsNullOrEmpty(configPath))
+ {
+ return (false, null, $"{configType}配置文件路径为空");
+ }
+
+ if (!File.Exists(configPath))
+ {
+ return (false, null, $"{configType}配置文件不存在: {configPath}");
+ }
+
+ var result = await _commandExecutor.ExecuteCommandAsync(
+ string.Format(COM_ADDR_TEMPLATE, configPath),
+ new CancellationTokenSource());
+
+ if (result.IsSuccess)
+ {
+ var comAddr = result.Output.Trim();
+ if (string.IsNullOrEmpty(comAddr))
+ {
+ return (false, null, $"{configType}配置文件中未找到com_addr值");
+ }
+ _logger.LogInformation("获取到{ConfigType} com_addr值: {ComAddr}", configType, comAddr);
+ return (true, comAddr, null);
+ }
+ else
+ {
+ return (false, null, $"获取{configType} com_addr值失败: {result.Error}");
+ }
+ }
+
+ private void EnsureDirectoriesExist(AppSettings appSettings)
+ {
+ if (!Directory.Exists(appSettings.TempDirectory))
+ {
+ Directory.CreateDirectory(appSettings.TempDirectory);
+ }
+ if (!Directory.Exists(appSettings.RanConfigDirectory))
+ {
+ Directory.CreateDirectory(appSettings.RanConfigDirectory);
+ }
+ if (!Directory.Exists(appSettings.MmeConfigDirectory))
+ {
+ Directory.CreateDirectory(appSettings.MmeConfigDirectory);
+ }
+ }
+
+ private bool CopyConfigFile(string sourcePath, string targetDirectory, Action updatePath, string configType)
+ {
+ if (!File.Exists(sourcePath))
+ {
+ _logger.LogError("{ConfigType}配置文件不存在: {FilePath}", configType, sourcePath);
+ return false;
+ }
+
+ var fileName = Path.GetFileName(sourcePath);
+ var tempPath = Path.Combine(targetDirectory, fileName);
+
+ // 始终复制到临时目录
+ File.Copy(sourcePath, tempPath, true);
+
+ // 如果不在目标目录下,则复制到该目录并更新路径
+ if (!sourcePath.StartsWith(targetDirectory))
+ {
+ var targetPath = Path.Combine(targetDirectory, fileName);
+ File.Copy(sourcePath, targetPath, true);
+ updatePath(targetPath);
+ _logger.LogInformation("{ConfigType}配置文件已复制到目标目录: {FilePath}", configType, targetPath);
+ }
+ else
+ {
+ _logger.LogInformation("{ConfigType}配置文件已在目标目录中: {FilePath}", configType, sourcePath);
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs b/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs
new file mode 100644
index 0000000..e99017b
--- /dev/null
+++ b/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs
@@ -0,0 +1,312 @@
+using CoreAgent.Domain.Entities;
+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 NetworkInterfaceManager : INetworkInterfaceManager
+{
+ private readonly ILogger _logger;
+ private readonly ISystemCommandExecutor _commandExecutor;
+ private readonly ICellularNetworkContext _context;
+ private const string NULL_CONFIG = "NULL";
+ private const string KILL_COMMAND_TEMPLATE = "ps -ef | grep {0} | grep -v grep | awk '{{print $2}}' | xargs kill -9";
+
+ public NetworkInterfaceManager(
+ ILogger logger,
+ ISystemCommandExecutor commandExecutor,
+ ICellularNetworkContext context)
+ {
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
+ _context = context ?? throw new ArgumentNullException(nameof(context));
+ }
+
+ ///
+ /// 执行初始化命令
+ ///
+ public async Task ExecuteInitializeCommandsAsync(bool isStartup = false)
+ {
+ try
+ {
+ var commands = _context.GetNetworkCommandConfig();
+ if (commands?.NetworkCommands != null)
+ {
+ var initCommands = commands.NetworkCommands
+ .Where(s => s.Type == NetworkCommandType.Initialize ||
+ (isStartup && s.Type == NetworkCommandType.PreNetworkOperation))
+ .ToArray();
+
+ foreach (var cmd in initCommands)
+ {
+ if (!await ExecuteCommandAsync(cmd))
+ {
+ _logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template);
+ }
+ }
+ }
+ return NetworkInterfaceOperationResult.Success();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "执行初始化命令失败");
+ return NetworkInterfaceOperationResult.Failure($"执行初始化命令失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 启用网络接口
+ ///
+ public async Task EnableAsync(NetworkConfiguration networkConfig)
+ {
+ try
+ {
+ // 验证配置
+ if (!ValidateConfig(networkConfig))
+ {
+ return NetworkInterfaceOperationResult.Failure("网络配置验证失败");
+ }
+
+ var commands = _context.GetNetworkCommandConfig();
+ var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.NetworkOperation);
+ if (startCommand == null)
+ {
+ return NetworkInterfaceOperationResult.Failure("未找到启动命令配置");
+ }
+
+ // 根据配置类型执行不同的启动命令
+ 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);
+ }
+
+ return NetworkInterfaceOperationResult.Failure("无有效配置,跳过启动");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "启动网络接口失败");
+ return NetworkInterfaceOperationResult.Failure($"启动网络接口失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 禁用网络接口
+ ///
+ public async Task DisableAsync(string neConfigKey)
+ {
+ try
+ {
+ await Task.CompletedTask.ConfigureAwait(false);
+ return NetworkInterfaceOperationResult.Success();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "停止网络配置失败");
+ return NetworkInterfaceOperationResult.Failure($"停止网络配置失败: {ex.Message}");
+ }
+ }
+
+ private async Task ExecuteCommandAsync(CommandTemplateConfig command)
+ {
+ try
+ {
+ if (command.CanBeKilled)
+ {
+ return await KillProcessAsync(command.Template, command.Timeout);
+ }
+
+ var result = await _commandExecutor.ExecuteCommandAsync(command.Template, new CancellationTokenSource(), command.Timeout);
+ return result.IsSuccess;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "执行命令失败: {Template}", command.Template);
+ return false;
+ }
+ }
+
+ private async Task KillProcessAsync(string template, int timeout)
+ {
+ string killCmd = string.Format(KILL_COMMAND_TEMPLATE, template);
+ var result = await _commandExecutor.ExecuteCommandAsync(killCmd, new CancellationTokenSource());
+ _logger.LogInformation("已终止进程: {Template}", template);
+ return result.IsSuccess;
+ }
+
+ ///
+ /// 验证网络配置是否有效
+ ///
+ private bool ValidateConfig(NetworkConfiguration config)
+ {
+ if (config == null)
+ {
+ _logger.LogError("网络配置为空");
+ return false;
+ }
+
+ // 验证RAG配置
+ if (!string.IsNullOrEmpty(config.RagConfig) && !File.Exists(config.RagConfig))
+ {
+ _logger.LogError("RAG配置文件不存在: {FilePath}", config.RagConfig);
+ return false;
+ }
+
+ // 验证核心网络和IMS配置
+ if (config.CoreOrImsConfigs != null)
+ {
+ foreach (var coreConfig in config.CoreOrImsConfigs)
+ {
+ if (!string.IsNullOrEmpty(coreConfig.CoreNetworkConfig) && !File.Exists(coreConfig.CoreNetworkConfig))
+ {
+ _logger.LogError("核心网络配置文件不存在: {FilePath}", coreConfig.CoreNetworkConfig);
+ return false;
+ }
+
+ if (!string.IsNullOrEmpty(coreConfig.ImsConfig) && !File.Exists(coreConfig.ImsConfig))
+ {
+ _logger.LogError("IMS配置文件不存在: {FilePath}", coreConfig.ImsConfig);
+ return false;
+ }
+ }
+ }
+
+ // 验证至少有一个有效配置
+ if (string.IsNullOrEmpty(config.RagConfig) && (config.CoreOrImsConfigs == null || !config.CoreOrImsConfigs.Any()))
+ {
+ _logger.LogError("没有有效的网络配置");
+ return false;
+ }
+
+ return true;
+ }
+
+ 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, new CancellationTokenSource());
+ return result.IsSuccess
+ ? NetworkInterfaceOperationResult.Success()
+ : NetworkInterfaceOperationResult.Failure($"执行RAG配置启动命令失败: {result.Error}");
+ }
+
+ private async Task ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
+ {
+ var commands = new List();
+ var secondaryConfigs = networkConfig.CoreOrImsConfigs.ToArray();
+
+ var secondaryTasks = new List>();
+
+ for (int i = 0; i < secondaryConfigs.Length; i++)
+ {
+ var config = secondaryConfigs[i];
+ var command = string.Format(startCommand.Template, i + 1);
+ var fullCommand = $"{command} {NULL_CONFIG} {config.CoreNetworkConfig} {config.ImsConfig}";
+
+ _logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
+ secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
+ }
+
+ // 等待所有次要配置命令执行完成
+ var secondaryResults = await Task.WhenAll(secondaryTasks);
+ if (secondaryResults.Any(r => !r.IsSuccess))
+ {
+ return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败");
+ }
+ return NetworkInterfaceOperationResult.Success();
+ }
+
+ private async Task 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.TokenSource);
+ return result.IsSuccess
+ ? NetworkInterfaceOperationResult.Success()
+ : NetworkInterfaceOperationResult.Failure($"执行单配置启动命令失败: {result.Error}");
+ }
+
+ private async Task ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
+ {
+ // 添加次要配置命令
+ var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
+ var secondaryTasks = new List>();
+
+ for (int i = 0; i < secondaryConfigs.Length; i++)
+ {
+ var config = secondaryConfigs[i];
+ var command = string.Format(startCommand.Template, i + 2);
+ var fullCommand = $"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}";
+
+ _logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
+ secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
+ }
+
+ // 等待所有次要配置命令执行完成
+ var secondaryResults = await Task.WhenAll(secondaryTasks);
+ if (secondaryResults.Any(r => !r.IsSuccess))
+ {
+ return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败");
+ }
+
+ // 执行主配置命令
+ var primaryConfig = networkConfig.CoreOrImsConfigs.FirstOrDefault(s => s.Index == 1);
+ if (primaryConfig != null)
+ {
+ var primaryCommand = string.Format(startCommand.Template, 1);
+ var fullCommand = $"{primaryCommand} {networkConfig.RagConfig} {primaryConfig.CoreNetworkConfig} {primaryConfig.ImsConfig}";
+
+ _logger.LogInformation("执行主配置启动命令: {Command}", fullCommand);
+ var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
+ if (!result.IsSuccess)
+ {
+ return NetworkInterfaceOperationResult.Failure($"主配置命令执行失败: {result.Error}");
+ }
+ }
+
+ return NetworkInterfaceOperationResult.Success();
+ }
+}
\ No newline at end of file