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