You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
13 KiB

using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
using CoreAgent.Infrastructure.Command.Factories;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace CoreAgent.Infrastructure.Services;
/// <summary>
/// 蜂窝网络服务实现
/// </summary>
public class CellularNetworkService : ICellularNetworkService
{
private readonly ILogger<CellularNetworkService> _logger;
private readonly CellularNetworkGlobalStatus _globalStatus;
private readonly ISystemCommandExecutorFactory _commandExecutorFactory;
private static readonly SemaphoreSlim _startLock = new SemaphoreSlim(1, 1);
public CellularNetworkService(
ILogger<CellularNetworkService> logger,
ISystemCommandExecutorFactory commandExecutorFactory)
{
_logger = logger;
_commandExecutorFactory = commandExecutorFactory;
_globalStatus = new CellularNetworkGlobalStatus
{
IsInitialized = false,
CurrentStatus = NetworkStatus.Unknown,
CurrentSignalStrength = SignalStrength.NoSignal,
CurrentNetworkType = NetworkType.Unknown,
CurrentTransmitPower = 0
};
}
public async Task<bool> StartAsync(string interfaceName, CellularNetworkConfig config)
{
try
{
// 使用信号量确保只能启动一次
if (!await _startLock.WaitAsync(TimeSpan.FromSeconds(5)))
{
_logger.LogWarning("蜂窝网络启动操作被锁定,可能已有其他启动操作正在进行");
return false;
}
try
{
if (_globalStatus.IsInitialized)
{
_logger.LogWarning("蜂窝网络已经初始化,不能重复启动");
return false;
}
_logger.LogInformation("正在启动蜂窝网络接口: {InterfaceName}", interfaceName);
// 1. 配置网络参数
var configResult = await ConfigureNetworkAsync(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. 更新全局状态
_globalStatus.IsInitialized = true;
_globalStatus.LastStartTime = DateTime.Now;
_globalStatus.CurrentStatus = NetworkStatus.Connected;
_globalStatus.CurrentSignalStrength = await GetSignalStrengthAsync(interfaceName);
_globalStatus.CurrentNetworkType = await GetNetworkTypeAsync(interfaceName);
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 启动成功", interfaceName);
return true;
}
finally
{
_startLock.Release();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "启动蜂窝网络接口 {InterfaceName} 失败", interfaceName);
return false;
}
}
public async Task<bool> StopAsync(string interfaceName)
{
try
{
if (!_globalStatus.IsInitialized)
{
_logger.LogWarning("蜂窝网络未初始化,无需停止");
return true;
}
_logger.LogInformation("正在停止蜂窝网络接口: {InterfaceName}", interfaceName);
// 1. 停止网络接口
var stopResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" admin=disable");
if (!stopResult)
{
_logger.LogError("停止蜂窝网络接口失败");
return false;
}
// 2. 更新全局状态
_globalStatus.IsInitialized = false;
_globalStatus.LastStopTime = DateTime.Now;
_globalStatus.CurrentStatus = NetworkStatus.Disconnected;
_globalStatus.CurrentSignalStrength = SignalStrength.NoSignal;
_globalStatus.CurrentNetworkType = NetworkType.Unknown;
_globalStatus.CurrentTransmitPower = 0;
_logger.LogInformation("蜂窝网络接口 {InterfaceName} 停止成功", interfaceName);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "停止蜂窝网络接口 {InterfaceName} 失败", interfaceName);
return false;
}
}
public async Task<NetworkStatus> GetNetworkStatusAsync(string interfaceName)
{
try
{
_logger.LogDebug("正在获取蜂窝网络状态: {InterfaceName}", interfaceName);
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络状态失败: {Error}", result.Error);
return NetworkStatus.Unknown;
}
var output = result.Output;
if (output.Contains("已连接", StringComparison.OrdinalIgnoreCase))
{
return NetworkStatus.Connected;
}
else if (output.Contains("已断开", StringComparison.OrdinalIgnoreCase))
{
return NetworkStatus.Disconnected;
}
return NetworkStatus.Unknown;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络状态失败: {InterfaceName}", interfaceName);
return NetworkStatus.Unknown;
}
}
public async Task<SignalStrength> GetSignalStrengthAsync(string interfaceName)
{
try
{
_logger.LogDebug("正在获取蜂窝网络信号强度: {InterfaceName}", interfaceName);
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络信号强度失败: {Error}", result.Error);
return SignalStrength.NoSignal;
}
var output = result.Output;
if (output.Contains("信号强度: 强", StringComparison.OrdinalIgnoreCase))
{
return SignalStrength.Strong;
}
else if (output.Contains("信号强度: 中", StringComparison.OrdinalIgnoreCase))
{
return SignalStrength.Medium;
}
else if (output.Contains("信号强度: 弱", StringComparison.OrdinalIgnoreCase))
{
return SignalStrength.Weak;
}
return SignalStrength.NoSignal;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络信号强度失败: {InterfaceName}", interfaceName);
return SignalStrength.NoSignal;
}
}
public async Task<NetworkType> GetNetworkTypeAsync(string interfaceName)
{
try
{
_logger.LogDebug("正在获取蜂窝网络类型: {InterfaceName}", interfaceName);
var result = await ExecuteCommandWithResultAsync($"netsh interface cellular show interfaces \"{interfaceName}\"");
if (!result.IsSuccess)
{
_logger.LogError("获取蜂窝网络类型失败: {Error}", result.Error);
return NetworkType.Unknown;
}
var output = result.Output;
if (output.Contains("5G", StringComparison.OrdinalIgnoreCase))
{
return NetworkType.G5;
}
else if (output.Contains("4G", StringComparison.OrdinalIgnoreCase))
{
return NetworkType.G4;
}
else if (output.Contains("3G", StringComparison.OrdinalIgnoreCase))
{
return NetworkType.G3;
}
else if (output.Contains("2G", StringComparison.OrdinalIgnoreCase))
{
return NetworkType.G2;
}
return NetworkType.Unknown;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取蜂窝网络类型失败: {InterfaceName}", interfaceName);
return NetworkType.Unknown;
}
}
public async Task<bool> SetTransmitPowerAsync(string interfaceName, int powerLevel)
{
try
{
if (!_globalStatus.IsInitialized)
{
_logger.LogWarning("蜂窝网络未初始化,无法设置发射功率");
return false;
}
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;
}
_globalStatus.CurrentTransmitPower = powerLevel;
_logger.LogInformation("蜂窝网络发射功率设置成功: {PowerLevel}", powerLevel);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "设置蜂窝网络发射功率失败: {InterfaceName}, {PowerLevel}", interfaceName, powerLevel);
return false;
}
}
public Task<CellularNetworkGlobalStatus> GetGlobalStatusAsync()
{
return Task.FromResult(_globalStatus);
}
private async Task<bool> ConfigureNetworkAsync(string interfaceName, CellularNetworkConfig config)
{
try
{
_logger.LogDebug("正在配置蜂窝网络参数: {InterfaceName}", interfaceName);
// 配置APN
var apnResult = await ExecuteCommandAsync($"netsh interface cellular set interface \"{interfaceName}\" apn=\"{config.Apn}\"");
if (!apnResult)
{
return false;
}
// 配置用户名和密码
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)
{
return false;
}
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "配置蜂窝网络参数失败: {InterfaceName}", interfaceName);
return false;
}
}
private async Task<bool> WaitForConnectionAsync(string interfaceName)
{
const int maxAttempts = 30;
const int delayMs = 1000;
for (int i = 0; i < maxAttempts; i++)
{
var status = await GetNetworkStatusAsync(interfaceName);
if (status == NetworkStatus.Connected)
{
return true;
}
await Task.Delay(delayMs);
}
return false;
}
private async Task<bool> ExecuteCommandAsync(string command)
{
try
{
var executor = _commandExecutorFactory.CreateExecutor();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await executor.ExecuteCommandAsync(command, cts);
if (!result.IsSuccess)
{
_logger.LogError("命令执行失败: {Command}, 错误: {Error}", command, result.Error);
return false;
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "执行命令失败: {Command}", command);
return false;
}
}
private async Task<CommandExecutionResult> ExecuteCommandWithResultAsync(string command)
{
try
{
var executor = _commandExecutorFactory.CreateExecutor();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
return await executor.ExecuteCommandAsync(command, cts);
}
catch (Exception ex)
{
_logger.LogError(ex, "执行命令失败: {Command}", command);
return CommandExecutionResult.Failure(ex.Message, 0);
}
}
}