seb-win-refactoring/SafeExamBrowser.SystemComponents/WirelessNetwork.cs

263 lines
6.2 KiB
C#

/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts;
using SimpleWifi;
using SimpleWifi.Win32;
using SimpleWifi.Win32.Interop;
namespace SafeExamBrowser.SystemComponents
{
public class WirelessNetwork // TODO: ISystemComponent<ISystemWirelessNetworkControl>
{
private readonly object @lock = new object();
// TODOprivate List<ISystemWirelessNetworkControl> controls;
private List<WirelessNetworkDefinition> networks;
private bool hasWifiAdapter;
private ILogger logger;
private IText text;
private Timer timer;
private Wifi wifi;
public WirelessNetwork(ILogger logger, IText text)
{
// TODOthis.controls = new List<ISystemWirelessNetworkControl>();
this.logger = logger;
this.networks = new List<WirelessNetworkDefinition>();
this.text = text;
}
public void Initialize()
{
wifi = new Wifi();
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
hasWifiAdapter = !wifi.NoWifiAvailable && !IsTurnedOff();
if (hasWifiAdapter)
{
UpdateAvailableNetworks();
StartTimer();
logger.Info("Started monitoring the wireless network adapter.");
}
else
{
logger.Info("Wireless networks cannot be monitored, as there is no hardware adapter available or it is turned off.");
}
}
// TODO
//public void Register(ISystemWirelessNetworkControl control)
//{
// if (hasWifiAdapter)
// {
// control.HasWirelessNetworkAdapter = true;
// control.NetworkSelected += Control_NetworkSelected;
// }
// else
// {
// control.HasWirelessNetworkAdapter = false;
// control.SetInformation(text.Get(TextKey.SystemControl_WirelessNotAvailable));
// }
// lock (@lock)
// {
// controls.Add(control);
// }
// if (hasWifiAdapter)
// {
// UpdateControls();
// }
//}
public void Terminate()
{
if (timer != null)
{
timer.Stop();
logger.Info("Stopped monitoring the wireless network adapter.");
}
// TODO
//foreach (var control in controls)
//{
// control.Close();
//}
}
private void Control_NetworkSelected(Guid id)
{
lock (@lock)
{
var network = networks.First(n => n.Id == id);
try
{
var request = new AuthRequest(network.AccessPoint);
logger.Info($"Attempting to connect to '{network.Name}'...");
network.AccessPoint.ConnectAsync(request, false, (success) => AccessPoint_OnConnectComplete(network.Name, success));
// TODO
//foreach (var control in controls)
//{
// control.IsConnecting = true;
//}
}
catch (Exception e)
{
logger.Error($"Failed to connect to wireless network '{network.Name}!'", e);
}
}
}
private void AccessPoint_OnConnectComplete(string name, bool success)
{
if (success)
{
logger.Info($"Successfully connected to wireless network '{name}'.");
}
else
{
logger.Error($"Failed to connect to wireless network '{name}!'");
}
lock (@lock)
{
// TODO
//foreach (var control in controls)
//{
// control.IsConnecting = false;
//}
}
UpdateAvailableNetworks();
UpdateControls();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
UpdateAvailableNetworks();
UpdateControls();
}
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
{
UpdateAvailableNetworks();
UpdateControls();
}
private bool IsTurnedOff()
{
try
{
var client = new WlanClient();
foreach (var @interface in client.Interfaces)
{
foreach (var state in @interface.RadioState.PhyRadioState)
{
if (state.dot11SoftwareRadioState == Dot11RadioState.On && state.dot11HardwareRadioState == Dot11RadioState.On)
{
return false;
}
}
}
}
catch (Exception e)
{
logger.Error("Failed to determine the radio state of the wireless adapter(s)! Assuming it is (all are) turned off...", e);
}
return true;
}
private void UpdateControls()
{
lock (@lock)
{
try
{
var currentNetwork = networks.FirstOrDefault(n => n.Status == WirelessNetworkStatus.Connected);
// TODO
//foreach (var control in controls)
//{
// if (wifi.ConnectionStatus == WifiStatus.Disconnected)
// {
// control.SetInformation(text.Get(TextKey.SystemControl_WirelessDisconnected));
// }
// if (currentNetwork != null)
// {
// control.SetInformation(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", currentNetwork.Name));
// }
// control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
// control.Update(networks.ToList());
//}
}
catch (Exception e)
{
logger.Error("Failed to update the wireless network adapter status!", e);
}
}
}
private void UpdateAvailableNetworks()
{
lock (@lock)
{
networks.Clear();
foreach (var accessPoint in wifi.GetAccessPoints())
{
// The user may only connect to an already configured wireless network!
if (accessPoint.HasProfile)
{
networks.Add(ToDefinition(accessPoint));
}
}
}
}
private void StartTimer()
{
const int FIVE_SECONDS = 5000;
timer = new Timer(FIVE_SECONDS);
timer.Elapsed += Timer_Elapsed;
timer.AutoReset = true;
timer.Start();
}
private WirelessNetworkDefinition ToDefinition(AccessPoint accessPoint)
{
return new WirelessNetworkDefinition
{
AccessPoint = accessPoint,
Name = accessPoint.Name,
SignalStrength = Convert.ToInt32(accessPoint.SignalStrength),
Status = accessPoint.IsConnected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected
};
}
private WirelessNetworkStatus ToStatus(WifiStatus status)
{
return status == WifiStatus.Connected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected;
}
}
}