aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs')
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs710
1 files changed, 0 insertions, 710 deletions
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
deleted file mode 100644
index 143f21f42..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
+++ /dev/null
@@ -1,710 +0,0 @@
-using Google.Protobuf;
-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;
-using System.Threading.Tasks;
-using Tango.Core;
-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.IFS;
-using Tango.PMR.Integration;
-using Tango.PMR.MachineStatus;
-using Tango.PMR.Power;
-using Tango.Transport;
-using Tango.Transport.Adapters;
-using Tango.Transport.Transporters;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeReceiver : BasicTransporter
- {
- /// <summary>
- /// A dictionary containing the last time a user name has made a request or response.
- /// This is used to bypass the safety operations confirmation.
- /// FullName, Contact Time
- /// </summary>
- public static Dictionary<String, DateTime> LastSafetyLevelContactsTimes { get; private set; }
-
- #region Message Handler
-
- private class MessageHandler
- {
- public Action<MessageContainer> Method { get; set; }
- public bool RequiresLogin { get; set; }
- public ExternalBridgeLoginIntent LoginIntent { get; set; }
-
- public MessageHandler(Action<MessageContainer> method)
- {
- Method = method;
- }
-
- public MessageHandler(Action<MessageContainer> method, ExternalBridgeLoginIntent intent) : this(method)
- {
- RequiresLogin = true;
- LoginIntent = intent;
- }
- }
-
- #endregion
-
- private String _eventsToken;
- private String _machineStatusToken;
- private String _diagnosticsToken;
- private String _debugLogsToken;
- private String _applicationLogsToken;
- private String _inkFillingToken;
-
- private IMachineOperator _machineOperator;
- private Dictionary<MessageType, MessageHandler> _messageHandlers;
-
- #region Events
-
- public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest;
- public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest;
- public event EventHandler Disconnected;
- public event EventHandler<ExternalBridgeReceiverRequestReceivedEventArgs> ReceiverRequestReceived;
-
- #endregion
-
- #region Properties
-
- public bool AllowSafetyLevelOperations { get; set; }
-
- 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; private set; }
- public bool RequiresInkFillingStatus { get; private set; }
-
- public bool IsLoggedIn { get; private set; }
- public ExternalBridgeLoginIntent LoginIntent { get; private set; }
- public String UserName { get; private set; }
-
- private ExternalBridgeLoginRequest _loginInfo;
- public ExternalBridgeLoginRequest LoginInfo
- {
- get { return _loginInfo; }
- set { _loginInfo = value; RaisePropertyChangedAuto(); }
- }
-
- public bool IsLoggedInAndRequiresDiagnostics
- {
- get { return IsLoggedIn && (LoginIntent == ExternalBridgeLoginIntent.Diagnostics || LoginIntent == ExternalBridgeLoginIntent.FullControl); }
- }
-
-
- #endregion
-
- #region Constructors
-
- static ExternalBridgeReceiver()
- {
- LastSafetyLevelContactsTimes = new Dictionary<string, DateTime>();
- }
-
- public ExternalBridgeReceiver(IMachineOperator machineOperator)
- {
- ComponentName = $"External Bridge Receiver {_component_counter++}";
-
- FailsWithAdapter = true;
-
- _machineOperator = machineOperator;
-
- _messageHandlers = new Dictionary<MessageType, MessageHandler>();
- UseKeepAlive = false;
- KeepAliveTimeout = TimeSpan.FromSeconds(10);
- KeepAliveRetries = 4;
-
- _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.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartApplicationLogsRequest, new MessageHandler(OnStartApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopApplicationLogsRequest, new MessageHandler(OnStopApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.JobRequest, new MessageHandler(OnJobRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartPowerDownRequest, new MessageHandler(OnStartPowerDownRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartInkFillingStatusRequest, new MessageHandler(OnStartInkFillingStatusRequest, ExternalBridgeLoginIntent.Diagnostics));
- }
-
- public ExternalBridgeReceiver(TcpClient tcpClient, IMachineOperator machineOperator) : this(machineOperator)
- {
- Adapter = new TcpTransportAdapter(tcpClient);
- }
-
- public ExternalBridgeReceiver(SignalRTransportAdapter signalRAdapter, IMachineOperator machineOperator) : this(machineOperator)
- {
- Adapter = signalRAdapter;
- }
-
- #endregion
-
- #region Override Methods
-
- protected override void OnRequestReceived(RequestReceivedEventArgs e)
- {
- base.OnRequestReceived(e);
-
- if (e.Handled) return;
-
- var container = e.Container;
-
- try
- {
- if (e.Container.Type == MessageType.ConfigureProtocolRequest)
- {
- var message = MessageFactory.ParseTangoMessageFromContainer<ConfigureProtocolRequest>(container);
- SendResponse(new ConfigureProtocolResponse() { Confirmed = true }, container.Token, new TransportResponseConfig() { Immediate = true, Priority = QueuePriority.High });
-
- Task.Factory.StartNew(() =>
- {
- Thread.Sleep(200);
- Adapter.EnableCompression = message.Message.EnableCompression;
- GenericProtocol = message.Message.GenericProtocol;
- });
- return;
- }
-
- if (!AllowSafetyLevelOperations)
- {
- if (ExternalBridgeService.SafetyLevelOperations.Contains(container.Type))
- {
- SendErrorResponse(new AuthenticationException("The specified action requires safety level permission that is not granted for the current session."), container.Token);
- return;
- }
- }
- else
- {
- if (UserName != null)
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
- }
-
- if (_messageHandlers.ContainsKey(container.Type))
- {
- 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);
- }
- catch (Exception ex)
- {
- SendErrorResponse(ex, container.Token);
- }
- }
- catch (Exception ex)
- {
- if (ex is ResponseErrorException)
- {
- SendResponse((ex as ResponseErrorException).Container);
- }
- else
- {
- SendErrorResponse(ex, container.Token);
- }
- }
- }
- else
- {
- if (IsLoggedIn)
- {
- ExternalBridgeReceiverRequestReceivedEventArgs args = new ExternalBridgeReceiverRequestReceivedEventArgs();
- args.Container = container;
- ReceiverRequestReceived?.Invoke(this, args);
-
- if (!args.Handled)
- {
- OnAnyRequest(container);
- }
- }
- }
- }
- catch (Exception ex)
- {
- 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);
- OnDisconnected();
- }
-
- public async override Task Disconnect()
- {
- try
- {
- if (IsLoggedIn)
- {
- await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(3), ShouldLog = true });
- }
- }
- 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 OnExternalBridgeLoginRequest(MessageContainer container)
- {
- var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container);
-
- LogManager.Log($"External bridge login attempt:\nIntent: {request.Message.Intent}\nMessage:\n{request.Message.ToJsonString()}");
-
- ExternalBridgeReceiverLoginRequestEventArgs args = new ExternalBridgeReceiverLoginRequestEventArgs((machine, deviceInfo, applicationInfo) =>
- {
- //Confirm
- LogManager.Log("External bridge client has logged-in successfully.");
-
- IsLoggedIn = true;
- LoginIntent = request.Message.Intent;
- UserName = request.Message.UserName;
- LoginInfo = request.Message;
-
- var response = new ExternalBridgeLoginResponse();
- response.Authenticated = true;
- response.SerialNumber = machine.SerialNumber;
- response.DeviceInformation = deviceInfo;
- response.ApplicationInformation = applicationInfo;
-
- AllowSafetyLevelOperations = request.Message.RequireSafetyLevelOperations;
-
- SendResponse<ExternalBridgeLoginResponse>(response, container.Token);
-
- UpdateMachineOperatorStatus((UpdateStatus)_machineOperator.Status);
-
- UseKeepAlive = true;
-
- if (AllowSafetyLevelOperations && UserName != null)
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
- },
- (reason) =>
- {
- //Decline
- SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = reason });
- Disconnect().GetAwaiter().GetResult();
- });
-
- args.Address = Adapter.Address;
- args.Request = request;
-
- LoginRequest?.Invoke(this, args);
- }
-
- protected virtual void OnExternalBridgeLogoutRequest(MessageContainer container)
- {
- try
- {
- SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex);
- }
- finally
- {
- OnDisconnected();
- ClearQueues();
- }
- }
-
- protected async virtual void OnAnyRequest(MessageContainer container)
- {
- if (!container.Continuous)
- {
- try
- {
- var response = await _machineOperator.SendRequest(container);
- await SendResponse(response);
- }
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- else
- {
- try
- {
- _machineOperator.SendContinuousRequest(container).Subscribe((response) =>
- {
- if (State == TransportComponentState.Connected)
- {
- SendResponse(response);
- }
-
- }, (ex) =>
- {
- if (State == TransportComponentState.Connected)
- {
- if (ex is ResponseErrorException)
- {
- SendResponse((ex as ResponseErrorException).Container);
- }
- else if (ex is ContinuousResponseAbortedException)
- {
- SendResponse((ex as ContinuousResponseAbortedException).Container);
- }
- }
- });
- }
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- }
-
- 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;
- SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsToken);
- RequiresDiagnostics = true;
- }
-
- protected virtual void OnStopDiagnosticsRequest(MessageContainer container)
- {
- if (_diagnosticsToken != null)
- {
- RequiresDiagnostics = false;
- SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsToken, new TransportResponseConfig() { Completed = true });
- _diagnosticsToken = null;
- SendResponse<StopDiagnosticsResponse>(new StopDiagnosticsResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartDebugLogRequest(MessageContainer container)
- {
- _debugLogsToken = container.Token;
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsToken);
- RequiresDebugLogs = true;
- }
-
- protected virtual void OnStopDebugLogRequest(MessageContainer container)
- {
- if (_debugLogsToken != null)
- {
- RequiresDebugLogs = false;
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsToken, new TransportResponseConfig() { Completed = true });
- _debugLogsToken = null;
- SendResponse<StopDebugLogResponse>(new StopDebugLogResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartEventsNotificationRequest(MessageContainer container)
- {
- _eventsToken = container.Token;
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsToken);
- RequiresEventsNotification = true;
- }
-
- protected virtual void OnStopEventsNotificationRequest(MessageContainer container)
- {
- if (_eventsToken != null)
- {
- RequiresEventsNotification = false;
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsToken, new TransportResponseConfig() { Completed = true });
- _eventsToken = null;
- SendResponse<StopEventsNotificationResponse>(new StopEventsNotificationResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartMachineStatusUpdateRequest(MessageContainer container)
- {
- _machineStatusToken = container.Token;
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusToken);
- RequiresMachineStatusUpdate = true;
- }
-
- protected virtual void OnStopMachineStatusUpdateRequest(MessageContainer container)
- {
- if (_machineStatusToken != null)
- {
- RequiresMachineStatusUpdate = false;
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusToken, new TransportResponseConfig() { Completed = true });
- _machineStatusToken = null;
- SendResponse<StopMachineStatusUpdateResponse>(new StopMachineStatusUpdateResponse(), container.Token);
- }
- }
-
- 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, new TransportResponseConfig() { Completed = 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, new TransportResponseConfig() { ErrorCode = ErrorCode.ContinuousResponseAborted, ErrorMessage = "Power down request is not supported via external bridge." });
- }
-
- protected virtual void OnStartInkFillingStatusRequest(MessageContainer container)
- {
- _inkFillingToken = container.Token;
- UpdateInkFillingStatus(null);
- RequiresInkFillingStatus = true;
- }
-
- #endregion
-
- #region Continuous Updates
-
- public void UpdateDiagnostics(MessageContainer container)
- {
- try
- {
- if (AllowSafetyLevelOperations && UserName != null) //Usually all clients require diagnostics so we will update the last contact time here..
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
-
- if (_diagnosticsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _diagnosticsToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateDebugLogs(MessageContainer container)
- {
- try
- {
- if (_debugLogsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _debugLogsToken;
- SendResponse(cloned, new TransportResponseConfig()
- {
- Priority = QueuePriority.Low,
- });
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateEvents(MessageContainer container)
- {
- try
- {
- if (_eventsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _eventsToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateMachineStatus(MessageContainer container)
- {
- try
- {
- if (_machineStatusToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _machineStatusToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateApplicationLogs(MessageContainer container)
- {
- try
- {
- if (_applicationLogsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _applicationLogsToken;
- SendResponse(cloned, new TransportResponseConfig() { Priority = QueuePriority.Low });
- }
- }
- 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);
- }
- }
-
- public void UpdateInkFillingStatus(MessageContainer container)
- {
- try
- {
- if (_inkFillingToken != null)
- {
- if (container == null)
- {
- container = new MessageContainer()
- {
- Continuous = true,
- Type = MessageType.StartInkFillingStatusResponse,
- Data = ByteString.CopyFrom((new StartInkFillingStatusResponse() { Status = _machineOperator.InkFillingStatus }).ToBytes())
- };
- }
- var cloned = container.Clone();
- cloned.Token = _inkFillingToken;
- SendResponse(cloned, new TransportResponseConfig());
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- #endregion
- }
-}