diff --git a/WifiSitter/WifiSitter.cs b/WifiSitter/WifiSitter.cs index 4c9bf9d..e2747d7 100644 --- a/WifiSitter/WifiSitter.cs +++ b/WifiSitter/WifiSitter.cs @@ -29,6 +29,7 @@ namespace WifiSitter private volatile bool _paused; private static WifiSitterIpc _wsIpc; private Action _handleMsgRecv; + private System.Timers.Timer _pauseTimer; #endregion // fields @@ -90,10 +91,17 @@ namespace WifiSitter LogLine("Version: {0}", v.ToString()); // Setup IPC + // TODO make this tunable, cmd argument? LogLine("Initializing IPC..."); _handleMsgRecv = new Action(HandleMsgReceived); _wsIpc = new WifiSitterIpc(_handleMsgRecv); + // Initialize timeout timer + _pauseTimer = new System.Timers.Timer(); + _pauseTimer.AutoReset = false; + _pauseTimer.Interval = 5 * 60 * 1000; // five minutes + _pauseTimer.Elapsed += (o, e) => { _paused = false; }; + // Check if there are any interfaces not detected by GetAllNetworkInterfaces() // That method will not show disabled interfaces _ignoreNics = ReadNicWhitelist(); @@ -260,6 +268,9 @@ namespace WifiSitter while (!_shutdownEvent.WaitOne(0)) { if (_paused) { + + // TODO do network state checks while paused so state can be sent to client, if client has polled in the last 90 seconds + Thread.Sleep(1000); continue; } @@ -332,6 +343,9 @@ namespace WifiSitter } private void ResetNicState (NetworkState netstate) { + if (netstate == null) + return; + var taskList = new List(); foreach (var n in netstate.OriginalNicState) { var id = n[0]; @@ -370,19 +384,35 @@ namespace WifiSitter WifiSitterIpcMessage _msg = null; try { _msg = Newtonsoft.Json.JsonConvert.DeserializeObject(e.DataGram.Message); } catch { LogLine("Deserialize to WifiSitterIpcMessage failed."); } - + WifiSitterIpcMessage response; if (_msg != null) { - if (_msg.Request == "get_netstate") { - LogLine("Sending netstate to: {0}", _msg.Requestor); - var response = new WifiSitterIpcMessage("give_netstate", _wsIpc.MyChannelName, "", Newtonsoft.Json.JsonConvert.SerializeObject(new Model.SimpleNetworkState(netstate))); - _wsIpc.MsgBroadcaster.SendToChannel(_msg.Target, response.IpcMessageJsonString()); + switch (_msg.Request) { + case "get_netstate": + LogLine("Sending netstate to: {0}", _msg.Requestor); + response = new WifiSitterIpcMessage("give_netstate", _wsIpc.MyChannelName, "", Newtonsoft.Json.JsonConvert.SerializeObject(new Model.SimpleNetworkState(netstate))); + _wsIpc.MsgBroadcaster.SendToChannel(_msg.Target, response.IpcMessageJsonString()); + break; + case "take_five": + try { + LogLine("Taking 5 minute break and restoring interfaces."); + _pauseTimer.Stop(); + _pauseTimer.Start(); + _paused = true; + ResetNicState(netstate); + response = new WifiSitterIpcMessage("taking_five", _wsIpc.MyChannelName, "", ""); + _wsIpc.MsgBroadcaster.SendToChannel(_msg.Target, response.IpcMessageJsonString()); + } + catch { WriteLog(LogType.error, "Failed to enter paused state after 'take_five' request received."); } + break; + default: + break; } } else { - Trace.WriteLine(e.DataGram.Message); + Trace.WriteLine(String.Format("Message issue: {0}", e.DataGram.Message)); } } - + #endregion // methods diff --git a/WifiSitterGui/TrayIconControl.xaml b/WifiSitterGui/TrayIconControl.xaml index 7a5fc6e..2f479fc 100644 --- a/WifiSitterGui/TrayIconControl.xaml +++ b/WifiSitterGui/TrayIconControl.xaml @@ -23,10 +23,12 @@ + ToolTip="Restores interfaces to original status." + Command="{Binding SendTakeFiveRequest}" /> + _handleMsgRcv; private static string _serviceChannel; - + private System.Timers.Timer _netstateCheckTimer; + #endregion // fields #region constructor @@ -43,16 +46,14 @@ namespace WifiSitterGui.ViewModel _handleMsgRcv = new Action(wsIpc_MessageReceived); _wsIpc = new WifiSitter.WifiSitterIpc(_handleMsgRcv); - Trace.WriteLine(String.Format("WifiSitter service msg channel: {0}", ServiceChannelName)); + // Intermittent network state polling + _netstateCheckTimer = new System.Timers.Timer(); + _netstateCheckTimer.AutoReset = true; + _netstateCheckTimer.Interval = 30 * 1000; // 30 seconds + _netstateCheckTimer.Elapsed += (o, e) => { RequestNetworkState(); }; + _netstateCheckTimer.Start(); - if (!String.IsNullOrEmpty(ServiceChannelName)) { - try { - _wsIpc.MsgBroadcaster.SendToChannel(ServiceChannelName, new WifiSitterIpcMessage("get_netstate", _wsIpc.MyChannelName, _wsIpc.MyChannelName).IpcMessageJsonString()); - } - catch (Exception e) { - Trace.WriteLine(e.Message); - } - } + Trace.WriteLine(String.Format("WifiSitter service msg channel: {0}", ServiceChannelName)); } #endregion // constructor @@ -82,19 +83,28 @@ namespace WifiSitterGui.ViewModel return _serviceChannel; } } - - private void GetServiceChannelName() { - - } - + #endregion // properties #region methods + + private void RequestNetworkState () { + if (!String.IsNullOrEmpty(ServiceChannelName)) { + try { + Trace.WriteLine("Checking for network state."); + _wsIpc.MsgBroadcaster.SendToChannel(ServiceChannelName, new WifiSitterIpcMessage("get_netstate", _wsIpc.MyChannelName, _wsIpc.MyChannelName).IpcMessageJsonString()); + } + catch (Exception e) { + Trace.WriteLine(e.Message); + } + } + } + #endregion // methods #region commands - public RelayCommand LaunchSettingsWindow { + public ICommand LaunchSettingsWindow { get { if (_launchWindowCommand == null) { _launchWindowCommand = new RelayCommand(() => { @@ -114,6 +124,20 @@ namespace WifiSitterGui.ViewModel } } + + public ICommand SendTakeFiveRequest { + get { + if (_takeFiveCommand == null) { + _takeFiveCommand = new RelayCommand(() => { + var request = new WifiSitterIpcMessage("take_five", _wsIpc.MyChannelName, _wsIpc.MyChannelName); + _wsIpc.MsgBroadcaster.SendToChannel(_serviceChannel, request.IpcMessageJsonString()); + // TODO need response validation mechanism + }); + } + return _takeFiveCommand; + } + } + #endregion // commands #region events @@ -129,11 +153,20 @@ namespace WifiSitterGui.ViewModel catch { Trace.WriteLine("Deserialize to ServiceRequest failed."); } if (_sr != null) { - if (_sr.Request == "give_netstate") { - try { - WindowVM.NetState = Newtonsoft.Json.JsonConvert.DeserializeObject(System.Text.Encoding.UTF8.GetString(_sr.Payload)); - } - catch { WifiSitter.WifiSitter.LogLine("Failed to deserialize netstate, payload."); } + switch (_sr.Request) { + case "give_netstate": + try { WindowVM.NetState = Newtonsoft.Json.JsonConvert.DeserializeObject(System.Text.Encoding.UTF8.GetString(_sr.Payload)); } + catch { WifiSitter.WifiSitter.LogLine("Failed to deserialize netstate, payload."); } + break; + case "taking_five": + Trace.WriteLine("Service paused."); + break; + case "service_status": + // TODO issue service status update + break; + default: + Trace.WriteLine(String.Format("Unknown request type: {0} from {1}", _sr?.Request, _sr?.Requestor)); + break; } } else {