aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2020-01-13 19:22:50 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2020-01-13 19:22:50 +0200
commitabd9951fb899fcaaba8235ec92088f16d10e3918 (patch)
treec2782956114543cb9536d65ca82342a117686395 /Software/Visual_Studio
parent9f3968271713394e958ba4829c11014958be44dc (diff)
downloadTango-abd9951fb899fcaaba8235ec92088f16d10e3918.tar.gz
Tango-abd9951fb899fcaaba8235ec92088f16d10e3918.zip
Working on external bridge v2
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs7
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs2
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs6
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs373
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs4
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs621
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs6
-rw-r--r--Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs49
-rw-r--r--Software/Visual_Studio/Tango.Logging/LogManager.cs1
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransporterBase.cs65
10 files changed, 479 insertions, 655 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
index 161a8cca7..e51247337 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
@@ -147,6 +147,13 @@ namespace Tango.MachineStudio.UI
}
catch { }
+ if (e.Exception.ToString().Contains("A Task's exception(s) were not observed"))
+ {
+ e.TryRecover = true;
+ LogManager.Log("Task not observed exception. Ignoring...");
+ return;
+ }
+
try
{
var eventLogger = TangoIOC.Default.GetInstance<IEventLogger>();
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
index 6d90ece73..9b818bd9d 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
@@ -81,7 +81,7 @@ namespace Tango.PPC.Common.Connection
MachineOperator.EnableJobResume = true;
MachineOperator.UseKeepAlive = true;
MachineOperator.EnableMachineStatusUpdates = true;
- MachineOperator.EnableDiagnostics = false;
+ MachineOperator.EnableDiagnostics = true;
MachineOperator.EnableEmbeddedDebugging = settings.EnableEmbeddedDebugLogs;
MachineOperator.EnableAutomaticThreadLoading = settings.EnableAutomaticThreadLoading;
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs
index ebe68a5d3..fd0e288c8 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs
@@ -111,6 +111,12 @@ namespace Tango.PPC.UI
return;
}
+ if (e.Exception.ToString().Contains("A Task's exception(s) were not observed"))
+ {
+ LogManager.Log("Task not observed exception. Ignoring...");
+ return;
+ }
+
try
{
LogManager.Log(e.Exception, "Application Crashed!");
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
index 057ff91d3..c43598746 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
@@ -1,17 +1,20 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.ExtensionMethods;
+using Tango.Integration.Operation;
using Tango.PMR;
using Tango.PMR.Common;
using Tango.PMR.Debugging;
using Tango.PMR.Diagnostics;
using Tango.PMR.Integration;
using Tango.PMR.MachineStatus;
+using Tango.PMR.Power;
using Tango.Transport;
using Tango.Transport.Adapters;
using Tango.Transport.Transporters;
@@ -20,6 +23,8 @@ namespace Tango.Integration.ExternalBridge
{
public class ExternalBridgeReceiver : BasicTransporter
{
+ #region Message Handler
+
private class MessageHandler
{
public Action<MessageContainer> Method { get; set; }
@@ -38,97 +43,196 @@ namespace Tango.Integration.ExternalBridge
}
}
+ #endregion
+
private String _eventsToken;
private String _machineStatusToken;
private String _diagnosticsToken;
private String _debugLogsToken;
+ private String _applicationLogsToken;
+ private IMachineOperator _machineOperator;
private Dictionary<MessageType, MessageHandler> _messageHandlers;
+ #region Events
+
public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest;
+ public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest;
+ public event EventHandler Disconnected;
+
+ #endregion
+
+ #region Properties
public bool RequiresDiagnostics { get; private set; }
public bool RequiresDebugLogs { get; private set; }
public bool RequiresEventsNotification { get; private set; }
public bool RequiresMachineStatusUpdate { get; private set; }
+ public bool RequiresApplicationLogs { get; set; }
public bool IsLoggedIn { get; private set; }
public ExternalBridgeLoginIntent LoginIntent { get; private set; }
- public ExternalBridgeReceiver()
+ public bool IsLoggedInAndRequiresDiagnostics
+ {
+ get { return IsLoggedIn && (LoginIntent == ExternalBridgeLoginIntent.Diagnostics || LoginIntent == ExternalBridgeLoginIntent.FullControl); }
+ }
+
+
+ #endregion
+
+ #region Constructors
+
+ public ExternalBridgeReceiver(IMachineOperator machineOperator)
{
+ ComponentName = "External Bridge Receiver";
+
+ _machineOperator = machineOperator;
+
_messageHandlers = new Dictionary<MessageType, MessageHandler>();
UseKeepAlive = false;
KeepAliveTimeout = TimeSpan.FromSeconds(5);
KeepAliveRetries = 2;
- _messageHandlers.Add(MessageType.ExternalBridgeLoginRequest, new MessageHandler(OnLoginRequest));
+ _messageHandlers.Add(MessageType.ExternalBridgeLoginRequest, new MessageHandler(OnExternalBridgeLoginRequest));
+ _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, new MessageHandler(OnExternalBridgeLogoutRequest));
+
+ _messageHandlers.Add(MessageType.ColorProfileRequest, new MessageHandler(OnColorProfileRequest));
+
+ _messageHandlers.Add(MessageType.StartDiagnosticsRequest, new MessageHandler(OnStartDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics));
+ _messageHandlers.Add(MessageType.StopDiagnosticsRequest, new MessageHandler(OnStopDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics));
+
+ _messageHandlers.Add(MessageType.StartDebugLogRequest, new MessageHandler(OnStartDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics));
+ _messageHandlers.Add(MessageType.StopDebugLogRequest, new MessageHandler(OnStopDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics));
+
+ _messageHandlers.Add(MessageType.StartEventsNotificationRequest, new MessageHandler(OnStartEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics));
+ _messageHandlers.Add(MessageType.StopEventsNotificationRequest, new MessageHandler(OnStopEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StartDiagnosticsRequest, new MessageHandler(OnStartDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
- _messageHandlers.Add(MessageType.StopDiagnosticsRequest, new MessageHandler(OnStopDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
+ _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
+ _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StartDebugLogRequest, new MessageHandler(OnStartDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
- _messageHandlers.Add(MessageType.StopDebugLogRequest, new MessageHandler(OnStopDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
+ _messageHandlers.Add(MessageType.StartApplicationLogsRequest, new MessageHandler(OnStartApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
+ _messageHandlers.Add(MessageType.StopApplicationLogsRequest, new MessageHandler(OnStopApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StartEventsNotificationRequest, new MessageHandler(OnStartEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
- _messageHandlers.Add(MessageType.StopEventsNotificationRequest, new MessageHandler(OnStopEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
+ _messageHandlers.Add(MessageType.JobRequest, new MessageHandler(OnJobRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
- _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl));
+ _messageHandlers.Add(MessageType.StartPowerDownRequest, new MessageHandler(OnStartPowerDownRequest, ExternalBridgeLoginIntent.Diagnostics));
}
- public ExternalBridgeReceiver(TcpClient tcpClient) : this()
+ public ExternalBridgeReceiver(TcpClient tcpClient, IMachineOperator machineOperator) : this(machineOperator)
{
Adapter = new TcpTransportAdapter(tcpClient);
}
+ #endregion
+
+ #region Override Methods
+
protected override void OnRequestReceived(MessageContainer container)
{
base.OnRequestReceived(container);
- if (_messageHandlers.ContainsKey(container.Type))
+ try
{
- var handler = _messageHandlers[container.Type];
-
- if (handler.RequiresLogin && (!IsLoggedIn || !LoginIntent.HasFlag(handler.LoginIntent)))
+ if (_messageHandlers.ContainsKey(container.Type))
{
- SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
- return;
- }
+ var handler = _messageHandlers[container.Type];
+
+ if (handler.RequiresLogin && (!IsLoggedIn || (int)handler.LoginIntent > (int)LoginIntent))
+ {
+ SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
+ return;
+ }
- try
- {
try
{
- handler.Method.Invoke(container);
+ try
+ {
+ handler.Method.Invoke(container);
+ }
+ catch (Exception ex)
+ {
+ SendErrorResponse(ex, container.Token);
+ }
}
catch (Exception ex)
{
- SendErrorResponse(ex, container.Token);
+ if (ex is ResponseErrorException)
+ {
+ SendResponse((ex as ResponseErrorException).Container);
+ }
+ else
+ {
+ SendErrorResponse(ex, container.Token);
+ }
}
}
- catch (Exception ex)
+ else
{
- if (ex is ResponseErrorException)
+ if (IsLoggedIn)
{
- SendResponse((ex as ResponseErrorException).Container);
- }
- else
- {
- SendErrorResponse(ex, container.Token);
+ OnAnyRequest(container);
}
}
}
- else
+ catch (Exception ex)
{
-
- OnAnyRequest(container);
+ LogManager.Log(ex, "Error occurred in processing request message on external bridge receiver.");
+ }
+ }
+
+ protected override void OnFailed(Exception ex)
+ {
+ if (ex is KeepAliveException)
+ {
+ LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session...");
}
+
+ base.OnFailed(ex);
}
+ public async override Task Disconnect()
+ {
+ try
+ {
+ if (IsLoggedIn)
+ {
+ await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5));
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending an external bridge log out request.");
+ }
+ finally
+ {
+ ClearQueues();
+ }
+
+ try
+ {
+ IsLoggedIn = false;
+ await base.Disconnect();
+ }
+ catch { }
+
+ OnDisconnected();
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ protected virtual void OnDisconnected()
+ {
+ Disconnected?.Invoke(this, new EventArgs());
+ }
+
+ #endregion
+
#region Message Handlers
- protected virtual void OnLoginRequest(MessageContainer container)
+ protected virtual void OnExternalBridgeLoginRequest(MessageContainer container)
{
var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container);
@@ -148,33 +252,50 @@ namespace Tango.Integration.ExternalBridge
response.DeviceInformation = deviceInfo;
SendResponse<ExternalBridgeLoginResponse>(response, container.Token);
+
+ UpdateMachineOperatorStatus((UpdateStatus)_machineOperator.Status);
+
+ UseKeepAlive = true;
},
- (reason) =>
+ (reason) =>
{
//Decline
SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, reason);
+ Disconnect().GetAwaiter().GetResult();
});
+
+ args.IpAddress = Adapter.Address;
+ args.Request = request;
+
+ LoginRequest?.Invoke(this, args);
}
- private void OnAnyRequest(MessageContainer container)
+ protected virtual void OnExternalBridgeLogoutRequest(MessageContainer container)
{
- if (SessionIntent == ExternalBridgeLoginIntent.ColorProfile)
+ try
+ {
+ SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
+ }
+ catch (Exception ex)
{
- await SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
- return;
+ LogManager.Log(ex);
}
+ finally
+ {
+ OnDisconnected();
+ ClearQueues();
+ }
+ }
+ protected async virtual void OnAnyRequest(MessageContainer container)
+ {
if (!container.Continuous)
{
try
{
- var response = await MachineOperator.SendRequest(container);
+ var response = await _machineOperator.SendRequest(container);
await SendResponse(response);
}
- //catch (TimeoutException)
- //{
-
- //}
catch (Exception ex)
{
await SendErrorResponse(ex, container.Token);
@@ -184,16 +305,16 @@ namespace Tango.Integration.ExternalBridge
{
try
{
- MachineOperator.SendContinuousRequest(container).Subscribe((response) =>
+ _machineOperator.SendContinuousRequest(container).Subscribe((response) =>
{
- if (Enabled && IsInSession)
+ if (State == TransportComponentState.Connected)
{
SendResponse(response);
}
}, (ex) =>
{
- if (Enabled)
+ if (State == TransportComponentState.Connected)
{
if (ex is ResponseErrorException)
{
@@ -209,6 +330,31 @@ namespace Tango.Integration.ExternalBridge
}
}
+ protected virtual void OnColorProfileRequest(MessageContainer container)
+ {
+ var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container);
+
+ ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () =>
+ {
+ //Approved.
+ await SendResponse<ColorProfileResponse>(new ColorProfileResponse()
+ {
+ Approved = true
+ }, container.Token);
+ await Task.Delay(500);
+ await base.Disconnect();
+ },
+ async () =>
+ {
+ //Declined.
+ await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token);
+ await Task.Delay(500);
+ await base.Disconnect();
+ });
+
+ ColorProfileRequest?.Invoke(this, e);
+ }
+
protected virtual void OnStartDiagnosticsRequest(MessageContainer container)
{
_diagnosticsToken = container.Token;
@@ -281,38 +427,149 @@ namespace Tango.Integration.ExternalBridge
}
}
+ protected virtual void OnStartApplicationLogsRequest(MessageContainer container)
+ {
+ _applicationLogsToken = container.Token;
+ SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken);
+ RequiresApplicationLogs = true;
+ }
+
+ protected virtual void OnStopApplicationLogsRequest(MessageContainer container)
+ {
+ if (_applicationLogsToken != null)
+ {
+ RequiresApplicationLogs = false;
+ SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken, true);
+ _applicationLogsToken = null;
+ SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse(), container.Token);
+ }
+ }
+
+ protected virtual void OnJobRequest(MessageContainer container)
+ {
+ if (LoginIntent != ExternalBridgeLoginIntent.FullControl)
+ {
+ throw new InvalidOperationException($"Job execution is disabled while session intent is '{LoginIntent}'.");
+ }
+ if (_machineOperator.IsPrinting)
+ {
+ throw new InvalidOperationException($"Could not execute job while machine operator status is '{_machineOperator.Status}'.");
+ }
+ else
+ {
+ OnAnyRequest(container);
+ }
+ }
+
+ protected virtual void OnStartPowerDownRequest(MessageContainer container)
+ {
+ SendResponse(new StartPowerDownResponse() { }, container.Token, false, ErrorCode.ContinuousResponseAborted, "Power down request is not supported via external bridge.");
+ }
+
#endregion
- public void UpdateDiagnostics(StartDiagnosticsResponse response)
+ #region Continuous Updates
+
+ public void UpdateDiagnostics(MessageContainer container)
{
- if (_diagnosticsToken != null)
+ try
{
- SendResponse<StartDiagnosticsResponse>(response, _diagnosticsToken);
+ if (_diagnosticsToken != null)
+ {
+ var cloned = container.Clone();
+ cloned.Token = _diagnosticsToken;
+ SendResponse(cloned);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
}
}
- public void UpdateDebugLogs(StartDebugLogResponse response)
+ public void UpdateDebugLogs(MessageContainer container)
{
- if (_debugLogsToken != null)
+ try
{
- SendResponse<StartDebugLogResponse>(response, _debugLogsToken);
+ if (_debugLogsToken != null)
+ {
+ var cloned = container.Clone();
+ cloned.Token = _debugLogsToken;
+ SendResponse(cloned);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
}
}
- public void UpdateEvents(StartEventsNotificationResponse response)
+ public void UpdateEvents(MessageContainer container)
{
- if (_eventsToken != null)
+ try
{
- SendResponse<StartEventsNotificationResponse>(response, _eventsToken);
+ if (_eventsToken != null)
+ {
+ var cloned = container.Clone();
+ cloned.Token = _eventsToken;
+ SendResponse(cloned);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
}
}
- public void UpdateMachineStatus(StartMachineStatusUpdateResponse response)
+ public void UpdateMachineStatus(MessageContainer container)
{
- if (_machineStatusToken != null)
+ try
+ {
+ if (_machineStatusToken != null)
+ {
+ var cloned = container.Clone();
+ cloned.Token = _machineStatusToken;
+ SendResponse(cloned);
+ }
+ }
+ catch (Exception ex)
{
- SendResponse<StartMachineStatusUpdateResponse>(response, _machineStatusToken);
+ Debug.WriteLine(ex);
}
}
+
+ public void UpdateApplicationLogs(MessageContainer container)
+ {
+ try
+ {
+ if (_applicationLogsToken != null)
+ {
+ var cloned = container.Clone();
+ cloned.Token = _applicationLogsToken;
+ SendResponse(cloned);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+
+ public void UpdateMachineOperatorStatus(UpdateStatus status)
+ {
+ try
+ {
+ SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest()
+ {
+ Status = status,
+ });
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
index e20b12d1a..d365de5c6 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
@@ -74,7 +74,9 @@ namespace Tango.Integration.ExternalBridge
if (_server == null)
{
- _server = new UdpClient(_settings.ExternalBridgeServiceDiscoveryPort);
+ _server = new UdpClient();
+ _server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _server.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort));
}
IsStarted = true;
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
index c4cca10f1..a0f81c835 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
@@ -31,16 +31,8 @@ namespace Tango.Integration.ExternalBridge
private List<ExternalBridgeReceiver> _receivers;
private UdpDiscoveryService<ExternalBridgeUdpDiscoveryPacket> _discoveryService;
private TcpServer _tcpServer;
- private bool _send_app_logs;
- private String _app_logs_token;
- private Dictionary<MessageType, Action<MessageContainer>> _messageHandlers;
private int _discovery_port = 8888; //Will be overridden by settings in constructor..
private int _external_bridge_port = 1984; //Will be overridden by settings in constructor..
- private String _eventsNotificationsToken;
- private String _machineStatusUpdateToken;
- private String _diagnosticsNotificationToken;
- private String _debugLogsNotificationToken;
- private bool _resend_diagnostics;
#region Events
@@ -143,9 +135,6 @@ namespace Tango.Integration.ExternalBridge
_discovery_port = settings.ExternalBridgeServiceDiscoveryPort;
_external_bridge_port = settings.ExternalBridgeServicePort;
- _messageHandlers = new Dictionary<MessageType, Action<MessageContainer>>();
- RegisterMessageHandlers();
-
_tcpServer = new TcpServer(_external_bridge_port);
_tcpServer.ClientConnected += _tcpServer_ClientConnected;
@@ -198,8 +187,6 @@ namespace Tango.Integration.ExternalBridge
{
if (MachineOperator != null)
{
- MachineOperator.StateChanged -= MachineOperator_StateChanged;
- MachineOperator.StateChanged += MachineOperator_StateChanged;
MachineOperator.StatusChanged -= MachineOperator_StatusChanged;
MachineOperator.StatusChanged += MachineOperator_StatusChanged;
MachineOperator.PendingResponseReceived -= MachineOperator_PendingResponseReceived;
@@ -218,159 +205,102 @@ namespace Tango.Integration.ExternalBridge
/// <param name="e">The <see cref="ClientConnectedEventArgs"/> instance containing the event data.</param>
private async void _tcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
{
- if (!IsInSession)
+ LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress());
+ ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket, MachineOperator);
+ receiver.LoginRequest += Receiver_LoginRequest;
+ receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
+ receiver.Disconnected += Receiver_Disconnected;
+ _receivers.Add(receiver);
+ await receiver.Connect();
+ }
+
+ private void MachineOperator_StatusChanged(object sender, MachineStatuses status)
+ {
+ try
{
- LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress());
- ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket);
- receiver.RequestReceived += Receiver_RequestReceived;
- _receivers.Add(receiver);
- await receiver.Connect();
+ _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics).ToList().ForEach(x => x.UpdateMachineOperatorStatus((UpdateStatus)status));
}
- else
+ catch (Exception ex)
{
- e.Socket.Dispose();
+ LogManager.Log(ex, "Error updating status of external bridge service client.");
}
}
- private void Receiver_RequestReceived(object sender, MessageContainer container)
+ private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e)
{
- ExternalBridgeReceiver receiver = sender as ExternalBridgeReceiver;
+ var toSend = _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresApplicationLogs).ToList();
- try
+ if (_receivers.Count > 0)
{
- if (Enabled)
+ var msg = MessageFactory.CreateTangoMessage<StartApplicationLogsResponse>(new StartApplicationLogsResponse()
{
- if (container.Type == MessageType.ConnectRequest || container.Type == MessageType.DisconnectRequest)
- {
- //Do nothing !
- }
- else
- {
- if (IsInSession)
- {
- if (container.Type == MessageType.ExternalBridgeLoginRequest)
- {
- receiver.SendErrorResponse(new AuthenticationException("Machine is already in session."), container.Token);
- return;
- }
+ LogItem = ByteString.CopyFrom(e.Serialize())
+ });
- if (_messageHandlers.ContainsKey(container.Type))
- {
- try
- {
- try
- {
- _messageHandlers[container.Type](container);
- }
- catch (Exception ex)
- {
- receiver.SendErrorResponse(ex, container.Token);
- }
- }
- catch (Exception ex)
- {
- if (ex is ResponseErrorException)
- {
- receiver.SendResponse((ex as ResponseErrorException).Container);
- }
- else
- {
- receiver.SendErrorResponse(ex, container.Token);
- }
- }
- }
- else
- {
- OnAnyRequest(container);
- }
- }
- else
- {
- if (container.Type == MessageType.ExternalBridgeLoginRequest)
- {
- OnExternalBridgeLoginRequest(container);
- }
- else if (container.Type == MessageType.ColorProfileRequest)
- {
- OnColorProfileRequest(container);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, String.Format("An error occurred while processing a request message '{0}' from the remote host.", container.Type));
+ msg.ToBytes();
+
+ toSend.ToList().ForEach(x => x.UpdateApplicationLogs(msg.Container));
}
}
- /// <summary>
- /// Machines the operator state changed.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The e.</param>
- private void MachineOperator_StateChanged(object sender, TransportComponentState e)
+ private void MachineOperator_PendingResponseReceived(object sender, MessageContainer container)
{
- //Do nothing right now.
- if (e != TransportComponentState.Connected)
+ OnOperatorResponseReceived(container);
+ }
+
+ #endregion
+
+ #region Receiver Events Handlers
+
+ private void Receiver_Disconnected(object sender, EventArgs e)
+ {
+ var receiver = sender as ExternalBridgeReceiver;
+ _receivers.Remove(receiver);
+ if (receiver.LoginIntent == ExternalBridgeLoginIntent.FullControl)
{
- _resend_diagnostics = true;
+ ClientDisconnected?.Invoke(this, new EventArgs());
}
}
- private async void MachineOperator_StatusChanged(object sender, MachineStatuses e)
+ private void Receiver_ColorProfileRequest(object sender, ColorProfileRequestEventArgs e)
{
- if (e == MachineStatuses.ReadyToDye && _machineOperator.State == TransportComponentState.Connected)
- {
- if (IsInSession && _resend_diagnostics)
- {
- _resend_diagnostics = false;
+ ColorProfileRequest?.Invoke(this, e);
+ }
- if (_diagnosticsNotificationToken != null)
- {
- var msg = MessageFactory.CreateTangoMessage<StartDiagnosticsRequest>(_diagnosticsNotificationToken);
- _machineOperator.SendContinuousRequest<StartDiagnosticsRequest, StartDiagnosticsResponse>(msg);
- }
- }
- }
+ private void Receiver_LoginRequest(object sender, ExternalBridgeReceiverLoginRequestEventArgs e)
+ {
+ var request = e.Request;
- if (IsInSession)
+ if (request.Intent == ExternalBridgeLoginIntent.FullControl && _receivers.Any(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl))
{
- try
- {
- UpdateStatus s = (UpdateStatus)e;
-
- await SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest()
- {
- Status = s,
- });
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error updating status of external bridge service client.");
- }
+ e.Decline("Only one full control client is allowed.");
+ return;
}
- }
- private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e)
- {
- if (State == TransportComponentState.Connected && _send_app_logs)
+ if (request.Intent == ExternalBridgeLoginIntent.FullControl && MachineOperator.IsPrinting)
{
- try
- {
- SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse()
- {
- LogItem = ByteString.CopyFrom(e.Serialize())
- }, _app_logs_token);
- }
- catch { }
+ e.Decline($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested.");
+ return;
}
- }
+ ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs();
+ args.Request = request;
+ args.IpAddress = e.IpAddress;
+ ConnectionRequest?.Invoke(this, args);
- private void MachineOperator_PendingResponseReceived(object sender, MessageContainer container)
- {
- OnOperatorResponseReceived(container);
+ var response = new ExternalBridgeLoginResponse();
+ response.Authenticated = args.Confirmed;
+ response.SerialNumber = Machine.SerialNumber;
+ response.DeviceInformation = MachineOperator.DeviceInformation;
+
+ if (args.Confirmed)
+ {
+ e.Confirm(Machine, MachineOperator.DeviceInformation);
+ }
+ else
+ {
+ e.Decline("Invalid password or intent.");
+ }
}
#endregion
@@ -403,16 +333,15 @@ namespace Tango.Integration.ExternalBridge
_tcpServer.Stop();
_discoveryService.Stop();
+ foreach (var receiver in _receivers.ToList())
+ {
+ await receiver.Disconnect();
+ }
+
IsStarted = false;
IsInSession = false;
_enabled = false;
RaisePropertyChanged(nameof(Enabled));
-
- try
- {
- await Disconnect();
- }
- catch { }
}
}
@@ -421,411 +350,39 @@ namespace Tango.Integration.ExternalBridge
/// </summary>
public async void DisconnectSession()
{
- await Disconnect();
- }
-
- #endregion
-
- #region Override Methods
-
- public async override Task Disconnect()
- {
- _send_app_logs = false;
-
- try
+ var sessionReceiver = _receivers.SingleOrDefault(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl);
+ if (sessionReceiver != null)
{
- if (IsInSession)
- {
- await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5));
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error sending an external bridge log out request.");
+ await sessionReceiver.Disconnect();
}
- finally
- {
- ClearQueues();
- }
-
- OnClientDisconnected();
}
- protected override void OnFailed(Exception ex)
- {
- if (ex is KeepAliveException)
- {
- LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session...");
- }
-
- base.OnFailed(ex);
- }
#endregion
#region Virtual Methods
- protected async virtual void OnClientDisconnected()
- {
- _eventsNotificationsToken = null;
- _machineStatusUpdateToken = null;
- _diagnosticsNotificationToken = null;
- _debugLogsNotificationToken = null;
- IsInSession = false;
- _send_app_logs = false;
-
- if (MachineOperator.State == TransportComponentState.Connected)
- {
- try
- {
- await MachineOperator.SendRequest(new StopDiagnosticsRequest());
- }
- catch (Exception ex)
- {
- LogManager.Log(ex);
- }
- }
-
- ClientDisconnected?.Invoke(this, new EventArgs());
-
- try
- {
- await base.Disconnect();
- }
- catch (Exception ex)
- {
- LogManager.Log(ex);
- }
-
- LogManager.Log("External bridge client disconnected.");
- }
-
protected virtual void OnOperatorResponseReceived(MessageContainer container)
{
try
{
- if (IsInSession)
+ switch (container.Type)
{
- if (container.Type == MessageType.StartEventsNotificationResponse)
- {
- if (_eventsNotificationsToken != null)
- {
- container.Token = _eventsNotificationsToken;
- SendResponse(container);
- }
- }
- if (container.Type == MessageType.StartMachineStatusUpdateResponse)
- {
- if (_machineStatusUpdateToken != null)
- {
- container.Token = _machineStatusUpdateToken;
- SendResponse(container);
- }
- }
- else if (container.Type == MessageType.StartDiagnosticsResponse)
- {
- if (_diagnosticsNotificationToken != null)
- {
- container.Token = _diagnosticsNotificationToken;
- SendResponse(container);
- }
- }
- else if (container.Type == MessageType.StartDebugLogResponse)
- {
- if (_debugLogsNotificationToken != null)
- {
- container.Token = _debugLogsNotificationToken;
- SendResponse(container);
- }
- }
+ case MessageType.StartDiagnosticsResponse:
+ _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDiagnostics).ToList().ForEach(x => x.UpdateDiagnostics(container));
+ break;
+ case MessageType.StartDebugLogResponse:
+ _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDebugLogs).ToList().ForEach(x => x.UpdateDebugLogs(container));
+ break;
+ case MessageType.StartEventsNotificationResponse:
+ _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresEventsNotification).ToList().ForEach(x => x.UpdateEvents(container));
+ break;
+ case MessageType.StartMachineStatusUpdateResponse:
+ _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresMachineStatusUpdate).ToList().ForEach(x => x.UpdateMachineStatus(container));
+ break;
}
- }
- catch { }
- }
-
- #endregion
-
- #region Message Handlers
- private void RegisterMessageHandlers()
- {
- _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, OnExternalBridgeLogoutRequest);
-
- _messageHandlers.Add(MessageType.StartApplicationLogsRequest, OnStartApplicationLogsRequest);
- _messageHandlers.Add(MessageType.StopApplicationLogsRequest, OnStopApplicationLogsRequest);
-
- _messageHandlers.Add(MessageType.JobRequest, OnJobRequest);
-
- //Events
- _messageHandlers.Add(MessageType.StartEventsNotificationRequest, OnStartEventsNotificationRequest);
- _messageHandlers.Add(MessageType.StopEventsNotificationRequest, OnStopEventsNotificationRequest);
-
- //Machine Status
- _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, OnStartMachineStatusUpdateRequest);
- _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, OnStopMachineStatusUpdateRequest);
-
- //Diagnostics
- _messageHandlers.Add(MessageType.StartDiagnosticsRequest, OnStartDiagnosticsRequest);
- _messageHandlers.Add(MessageType.StopDiagnosticsRequest, OnStopDiagnosticsRequest);
-
- //Debug Logs
- _messageHandlers.Add(MessageType.StartDebugLogRequest, OnStartDebugLogRequest);
- _messageHandlers.Add(MessageType.StopDebugLogRequest, OnStopDebugLogRequest);
-
- //Start Power Down
- _messageHandlers.Add(MessageType.StartPowerDownRequest, OnStartPowerDownRequest);
- }
-
- protected virtual async void OnAnyRequest(MessageContainer container)
- {
- if (SessionIntent == ExternalBridgeLoginIntent.ColorProfile)
- {
- await SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
- return;
}
-
- if (!container.Continuous)
- {
- try
- {
- var response = await MachineOperator.SendRequest(container);
- await SendResponse(response);
- }
- //catch (TimeoutException)
- //{
-
- //}
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- else
- {
- try
- {
- MachineOperator.SendContinuousRequest(container).Subscribe((response) =>
- {
- if (Enabled && IsInSession)
- {
- SendResponse(response);
- }
-
- }, (ex) =>
- {
- if (Enabled)
- {
- if (ex is ResponseErrorException)
- {
- SendResponse((ex as ResponseErrorException).Container);
- }
- }
- });
- }
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- }
-
- protected async virtual void OnExternalBridgeLoginRequest(MessageContainer container)
- {
- var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container);
-
- LogManager.Log($"External bridge login attempt:\nIntent: {request.Message.Intent}\nMessage:\n{request.Message.ToJsonString()}");
-
- if (MachineOperator.Status != MachineStatuses.Printing || request.Message.Intent != ExternalBridgeLoginIntent.FullControl)
- {
- ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs();
- args.Request = request;
- args.IpAddress = Adapter.Address;
- ConnectionRequest?.Invoke(this, args);
-
- var response = new ExternalBridgeLoginResponse();
- response.Authenticated = args.Confirmed;
- response.SerialNumber = Machine.SerialNumber;
- response.DeviceInformation = MachineOperator.DeviceInformation;
-
- IsInSession = args.Confirmed;
-
- if (IsInSession)
- {
- LogManager.Log("External bridge client has logged-in successfully.");
- UseKeepAlive = true;
- MachineOperator.EnableDiagnostics = false;
- SessionIntent = request.Message.Intent;
- }
- else
- {
- LogManager.Log("External bridge client login failed, invalid password.");
- }
-
- await SendResponse<ExternalBridgeLoginResponse>(response, container.Token, null, null, IsInSession ? null : "Invalid password or intent.");
- }
- else
- {
- LogManager.Log($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested.");
- await SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, $"Machine connection with '{ExternalBridgeLoginIntent.FullControl}' intent is not permitted while printing.");
- }
- }
-
- protected async virtual void OnExternalBridgeLogoutRequest(MessageContainer container)
- {
- try
- {
- await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex);
- }
- finally
- {
- ClearQueues();
- }
-
- OnClientDisconnected();
- }
-
- protected virtual void OnStartApplicationLogsRequest(MessageContainer container)
- {
- if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl)
- {
- _app_logs_token = container.Token;
- _send_app_logs = true;
- SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), container.Token);
- }
- else
- {
- throw new AuthenticationException("The specified intent does not grant the specified action.");
- }
- }
-
- protected virtual void OnStopApplicationLogsRequest(MessageContainer container)
- {
- if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl)
- {
- _send_app_logs = false;
- SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse() { }, container.Token);
- SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { }, _app_logs_token, true);
- }
- else
- {
- throw new AuthenticationException("The specified intent does not grant the specified action.");
- }
- }
-
- protected virtual void OnJobRequest(MessageContainer container)
- {
- if (SessionIntent != ExternalBridgeLoginIntent.FullControl)
- {
- throw new InvalidOperationException($"Job execution is disabled while session intent is '{SessionIntent}'.");
- }
- if (MachineOperator.IsPrinting)
- {
- throw new InvalidOperationException($"Could not execute job while machine operator status is '{MachineOperator.Status}'.");
- }
- else
- {
- OnAnyRequest(container);
- }
- }
-
- protected virtual void OnStartEventsNotificationRequest(MessageContainer container)
- {
- _eventsNotificationsToken = container.Token;
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), container.Token);
- }
-
- protected virtual void OnStopEventsNotificationRequest(MessageContainer container)
- {
- if (_eventsNotificationsToken != null)
- {
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsNotificationsToken, true);
- _eventsNotificationsToken = null;
- SendResponse<StopEventsNotificationResponse>(new StopEventsNotificationResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartMachineStatusUpdateRequest(MessageContainer container)
- {
- _machineStatusUpdateToken = container.Token;
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), container.Token);
- }
-
- protected virtual void OnStopMachineStatusUpdateRequest(MessageContainer container)
- {
- if (_machineStatusUpdateToken != null)
- {
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusUpdateToken, true);
- _machineStatusUpdateToken = null;
- SendResponse<StopMachineStatusUpdateResponse>(new StopMachineStatusUpdateResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartDiagnosticsRequest(MessageContainer container)
- {
- if (_diagnosticsNotificationToken == null)
- {
- _diagnosticsNotificationToken = container.Token;
- _machineOperator.SendContinuousRequest(container);
- }
- }
-
- private void OnStopDiagnosticsRequest(MessageContainer container)
- {
- if (_diagnosticsNotificationToken != null)
- {
- SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsNotificationToken, true);
- _diagnosticsNotificationToken = null;
- SendResponse<StopDiagnosticsResponse>(new StopDiagnosticsResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartDebugLogRequest(MessageContainer container)
- {
- _debugLogsNotificationToken = container.Token;
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), container.Token);
- }
-
- private void OnStopDebugLogRequest(MessageContainer container)
- {
- if (_debugLogsNotificationToken != null)
- {
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsNotificationToken, true);
- _debugLogsNotificationToken = null;
- SendResponse<StopDebugLogResponse>(new StopDebugLogResponse(), container.Token);
- }
- }
-
- private void OnColorProfileRequest(MessageContainer container)
- {
- var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container);
-
- ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () =>
- {
- //Approved.
- await SendResponse<ColorProfileResponse>(new ColorProfileResponse()
- {
- Approved = true
- }, container.Token);
- await Task.Delay(500);
- await base.Disconnect();
- },
- async () =>
- {
- //Declined.
- await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token);
- await Task.Delay(500);
- await base.Disconnect();
- });
-
- ColorProfileRequest?.Invoke(this, e);
- }
-
- private void OnStartPowerDownRequest(MessageContainer container)
- {
- SendResponse(new StartPowerDownResponse() { }, container.Token, false, ErrorCode.ContinuousResponseAborted, "Power down request is not supported via external bridge.");
+ catch { }
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
index 573cabb87..bc5323e13 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
@@ -117,8 +117,6 @@ namespace Tango.Integration.ExternalBridge
await Adapter.Disconnect();
throw new AuthenticationException(response.Container.ErrorMessage);
}
-
- Status = MachineStatuses.ReadyToDye;
}
catch (Exception ex)
{
@@ -299,7 +297,11 @@ namespace Tango.Integration.ExternalBridge
LogManager.Log("External Bridge TCP client disconnected by the remote host.");
}
catch { }
+
+ SessionLogger.EndSession();
SessionClosed?.Invoke(this, new EventArgs());
+
+ NotifyContinuousRequestMessagesDisconnection();
}
}
diff --git a/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs
index 7c325ee19..dab06455c 100644
--- a/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs
+++ b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs
@@ -13,50 +13,28 @@ namespace Tango.Logging
[Serializable]
public class ExceptionLogItem : LogItemBase
{
+ private bool _messageSet;
+
+ [NonSerialized]
+ private Exception _exception;
/// <summary>
/// Gets or sets the log item exception.
/// </summary>
- public Exception Exception { get; set; }
+ public Exception Exception
+ {
+ get { return _exception; }
+ set { _exception = value; }
+ }
/// <summary>
- /// Gets or sets the error description.
+ /// Gets the log message.
/// </summary>
- public String Description { get; set; }
+ public override string Message { get; set; }
/// <summary>
- /// Gets the log message.
+ /// Gets or sets the error description.
/// </summary>
- public override string Message
- {
- get
- {
- if (Exception is AggregateException)
- {
- try
- {
- String message = String.Empty;
-
- if (Description != null)
- {
- message += Description + Environment.NewLine;
- }
-
- message += String.Join(Environment.NewLine, (Exception as AggregateException).InnerExceptions.Select(x => x.Message));
-
- return message;
- }
- catch
- {
- return Exception.Message;
- }
- }
- else
- {
- return Exception.Message;
- }
- }
- set { }
- }
+ public String Description { get; set; }
/// <summary>
/// Returns a formatted string of the log item.
@@ -65,6 +43,5 @@ namespace Tango.Logging
{
return String.Format("[{0}] [{6}] [{1}] [{2}] [{3}]: {4}{5}", TimeStamp.ToString("HH:mm:ss.ff"), GetRelativeCallerFilePath(), CallerMethodName, CallerLineNumber, Description, Environment.NewLine + Exception.FlattenException(), Category);
}
-
}
}
diff --git a/Software/Visual_Studio/Tango.Logging/LogManager.cs b/Software/Visual_Studio/Tango.Logging/LogManager.cs
index 98bcaaa28..4f5bbb2ca 100644
--- a/Software/Visual_Studio/Tango.Logging/LogManager.cs
+++ b/Software/Visual_Studio/Tango.Logging/LogManager.cs
@@ -124,6 +124,7 @@ namespace Tango.Logging
log.Exception = e;
log.Category = category;
log.Description = description;
+ log.Message = log.Description + Environment.NewLine + log.Exception.FlattenException();
AppendLog(log);
diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
index 7f8bfa016..b8aa96ea6 100644
--- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
+++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
@@ -272,6 +272,26 @@ namespace Tango.Transport
return Adapter != null ? $"{ComponentName} ({Adapter.Address})" : ComponentName;
}
+ /// <summary>
+ /// Notifies all the continuous request messages about disconnection.
+ /// </summary>
+ protected virtual void NotifyContinuousRequestMessagesDisconnection()
+ {
+ LogManager.Log("Notifying all continuous request messages about disconnection...");
+ foreach (var request in _pendingRequests.ToList().Where(x => x.Direction == TransportMessageDirection.Request && x.IsContinuous))
+ {
+ try
+ {
+ LogManager.Log($"Notifying continuous request '{(request.Message as ITangoMessage).Type}'...");
+ request.SetException(new TransporterDisconnectedException("Transporter disconnected."));
+ }
+ catch (Exception e)
+ {
+ System.Diagnostics.Debug.WriteLine(e.ToString());
+ }
+ }
+ }
+
#endregion
#region Constructors
@@ -358,19 +378,7 @@ namespace Tango.Transport
}
LogManager.Log($"{GetExtendedComponentName()}: Transporter Disconnected...");
- LogManager.Log("Notifying all continuous request messages about disconnection...");
- foreach (var request in _pendingRequests.ToList().Where(x => x.Direction == TransportMessageDirection.Request && x.IsContinuous))
- {
- try
- {
- LogManager.Log($"Notifying continuous request '{(request.Message as ITangoMessage).Type}'...");
- request.SetException(new TransporterDisconnectedException("Transporter disconnected."));
- }
- catch (Exception e)
- {
- System.Diagnostics.Debug.WriteLine(e.ToString());
- }
- }
+ NotifyContinuousRequestMessagesDisconnection();
}
/// <summary>
@@ -909,20 +917,27 @@ namespace Tango.Transport
/// </summary>
protected void StartThreads()
{
- _pullThread = new Thread(PullThreadMethod);
- _pullThread.Name = $"{GetExtendedComponentName()} Pull Thread";
- _pullThread.IsBackground = true;
- _pullThread.Start();
+ try
+ {
+ _pullThread = new Thread(PullThreadMethod);
+ _pullThread.Name = $"{GetExtendedComponentName()} Pull Thread";
+ _pullThread.IsBackground = true;
+ _pullThread.Start();
- _pushThread = new Thread(PushThreadMethod);
- _pushThread.Name = $"{GetExtendedComponentName()} Push Thread";
- _pushThread.IsBackground = true;
- _pushThread.Start();
+ _pushThread = new Thread(PushThreadMethod);
+ _pushThread.Name = $"{GetExtendedComponentName()} Push Thread";
+ _pushThread.IsBackground = true;
+ _pushThread.Start();
- _keepAliveThread = new Thread(KeepAliveThreadMethod);
- _keepAliveThread.Name = $"{GetExtendedComponentName()} KeepAlive Thread";
- _keepAliveThread.IsBackground = true;
- _keepAliveThread.Start();
+ _keepAliveThread = new Thread(KeepAliveThreadMethod);
+ _keepAliveThread.Name = $"{GetExtendedComponentName()} KeepAlive Thread";
+ _keepAliveThread.IsBackground = true;
+ _keepAliveThread.Start();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error starting transporter threads.");
+ }
}
/// <summary>