diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs')
| -rw-r--r-- | Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs | 710 |
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 - } -} |
