aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-27 23:49:32 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-27 23:49:32 +0200
commit5f45be5bae69be7b7e916f02fb6d69b2db60e529 (patch)
tree9aff84020b5eca21df7bf0a7b5439e073969cec1 /Software
parent03970962af1bfbfc5c13109c3f0a465cf9a1dc29 (diff)
downloadTango-5f45be5bae69be7b7e916f02fb6d69b2db60e529.tar.gz
Tango-5f45be5bae69be7b7e916f02fb6d69b2db60e529.zip
Implemented Generic messages support!
Implemented custom external bridge request handlers.
Diffstat (limited to 'Software')
-rw-r--r--Software/PMR/Messages/Common/MessageType.proto2
-rw-r--r--Software/PMR/Messages/Integration/GenericRequest.proto10
-rw-r--r--Software/PMR/Messages/Integration/GenericResponse.proto9
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/App.xaml29
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj8
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Themes/Generic.xaml10
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml13
-rw-r--r--Software/Visual_Studio/Tango.Console/ConsoleControl.xaml6
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs10
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs20
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs102
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj3
-rw-r--r--Software/Visual_Studio/Tango.PMR/Common/MessageType.cs163
-rw-r--r--Software/Visual_Studio/Tango.PMR/Integration/GenericRequest.cs187
-rw-r--r--Software/Visual_Studio/Tango.PMR/Integration/GenericResponse.cs159
-rw-r--r--Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj2
-rw-r--r--Software/Visual_Studio/Tango.Transport/ITransporter.cs20
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransporterBase.cs39
22 files changed, 778 insertions, 86 deletions
diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto
index 3e5b54456..72314b62b 100644
--- a/Software/PMR/Messages/Common/MessageType.proto
+++ b/Software/PMR/Messages/Common/MessageType.proto
@@ -136,6 +136,8 @@ enum MessageType
ColorProfileResponse = 1014;
UpdateStatusRequest = 1015;
UpdateStatusResponse = 1016;
+ GenericRequest = 1017;
+ GenericResponse = 1018;
diff --git a/Software/PMR/Messages/Integration/GenericRequest.proto b/Software/PMR/Messages/Integration/GenericRequest.proto
new file mode 100644
index 000000000..0bc44d5fa
--- /dev/null
+++ b/Software/PMR/Messages/Integration/GenericRequest.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package Tango.PMR.Integration;
+option java_package = "com.twine.tango.pmr.integration";
+
+message GenericRequest
+{
+ string Type = 1;
+ bytes Data = 2;
+} \ No newline at end of file
diff --git a/Software/PMR/Messages/Integration/GenericResponse.proto b/Software/PMR/Messages/Integration/GenericResponse.proto
new file mode 100644
index 000000000..555f08bb5
--- /dev/null
+++ b/Software/PMR/Messages/Integration/GenericResponse.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package Tango.PMR.Integration;
+option java_package = "com.twine.tango.pmr.integration";
+
+message GenericResponse
+{
+ bytes Data = 2;
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/App.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/App.xaml
index 4ad5d146a..cfb949890 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/App.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/App.xaml
@@ -4,6 +4,35 @@
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
+
+
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.lightblue.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/materialdesigncolor.yellow.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.CheckBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ListBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.RadioButton.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.TextBlock.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Label.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Slider.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
+
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Converters.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Fonts.xaml" />
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
index 6bd5c2a77..9fc74f443 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
@@ -119,6 +119,10 @@
<Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
<Name>Tango.BL</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Console\Tango.Console.csproj">
+ <Project>{199e8359-cad3-433d-9eed-2027652b24a4}</Project>
+ <Name>Tango.Console</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj">
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
@@ -161,6 +165,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Themes\Generic.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\MainView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Themes/Generic.xaml
new file mode 100644
index 000000000..15f6b9b0b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Themes/Generic.xaml
@@ -0,0 +1,10 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Themes">
+
+
+ <!--<ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="pack://application:,,,/Tango.Console;component/Resources/Converters.xaml" />
+ </ResourceDictionary.MergedDictionaries>-->
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
index 8e1b4f920..97c55aba2 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.Console;
using Tango.FSE.Common;
using Tango.FSE.Common.Navigation;
using Tango.SharedUI.Helpers;
@@ -12,6 +13,33 @@ namespace Tango.FSE.PPCConsole.ViewModels
{
public class MainViewVM : FSEViewModel
{
+ public ConsoleControlVM ConsoleVM { get; set; }
+
+ public MainViewVM()
+ {
+ ConsoleVM = new ConsoleControlVM();
+ ConsoleVM.CommandExecuting += ConsoleVM_CommandExecuting;
+ ConsoleVM.Clear();
+ }
+
+ private async void ConsoleVM_CommandExecuting(object sender, ConsoleCommandExecutingEventArgs e)
+ {
+ await Task.Delay(1000);
+ try
+ {
+ var result = await MachineProvider.MachineOperator.SendGenericRequest<ConsoleCommandDTO, ConsoleCommandExecutionResult>(new ConsoleCommandDTO()
+ {
+ Command = e.Command.CommandText,
+ WorkingFolder = e.Command.WorkingFolder,
+ });
+ e.Complete(result.Output, result.WorkingFolder);
+ }
+ catch (Exception ex)
+ {
+ e.Complete(ex.FlattenMessage(), e.Command.WorkingFolder);
+ }
+ }
+
public override void OnApplicationStarted()
{
InvokeUI(() =>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
index 174e2bde4..edc45ba93 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
@@ -6,9 +6,20 @@
xmlns:global="clr-namespace:Tango.FSE.PPCConsole"
xmlns:vm="clr-namespace:Tango.FSE.PPCConsole.ViewModels"
xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Views"
+ xmlns:console="clr-namespace:Tango.Console;assembly=Tango.Console"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
<Grid>
- <TextBlock FontSize="60" HorizontalAlignment="Center" VerticalAlignment="Center">PPC Console</TextBlock>
+ <DockPanel>
+ <TextBlock DockPanel.Dock="Top" Margin="10" HorizontalAlignment="Center" FontSize="30">PPC Console</TextBlock>
+ <console:ConsoleControl BorderBrush="{StaticResource FSE_BorderBrush}" Margin="10" DataContext="{Binding ConsoleVM}">
+ <console:ConsoleControl.BusyTemplate>
+ <DataTemplate>
+ <ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}" IsIndeterminate="True" Width="16" Height="16" />
+ </DataTemplate>
+ </console:ConsoleControl.BusyTemplate>
+ </console:ConsoleControl>
+ </DockPanel>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/Tango.Console/ConsoleControl.xaml b/Software/Visual_Studio/Tango.Console/ConsoleControl.xaml
index fba10403a..6b0aaf8b6 100644
--- a/Software/Visual_Studio/Tango.Console/ConsoleControl.xaml
+++ b/Software/Visual_Studio/Tango.Console/ConsoleControl.xaml
@@ -35,11 +35,11 @@
<DataTemplate>
<StackPanel Margin="0 0 0 10">
<StackPanel Orientation="Horizontal">
- <TextBlock>
+ <TextBlock VerticalAlignment="Center">
<Run Text="{Binding WorkingFolder}"></Run><Run Text=">"></Run>
</TextBlock>
- <StackPanel Margin="5 0 0 0" Orientation="Horizontal">
- <TextBox IsReadOnly="True" Cursor="Arrow" AcceptsReturn="True" Background="Transparent" BorderThickness="0" Foreground="{Binding ElementName=control,Path=Foreground}" CaretBrush="{Binding ElementName=control,Path=CaretBrush}" SelectionBrush="{Binding ElementName=control,Path=SelectionBrush}" Text="{Binding CommandText}"></TextBox>
+ <StackPanel VerticalAlignment="Center" Margin="5 0 0 0" Orientation="Horizontal">
+ <TextBox VerticalAlignment="Center" IsReadOnly="True" Cursor="Arrow" AcceptsReturn="True" Background="Transparent" BorderThickness="0" Foreground="{Binding ElementName=control,Path=Foreground}" CaretBrush="{Binding ElementName=control,Path=CaretBrush}" SelectionBrush="{Binding ElementName=control,Path=SelectionBrush}" Text="{Binding CommandText}"></TextBox>
</StackPanel>
</StackPanel>
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
index 679e665f0..400f58c77 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
@@ -59,6 +59,7 @@ namespace Tango.Integration.ExternalBridge
public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest;
public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest;
public event EventHandler Disconnected;
+ public event EventHandler<ExternalBridgeReceiverRequestReceivedEventArgs> ReceiverRequestReceived;
#endregion
@@ -178,7 +179,14 @@ namespace Tango.Integration.ExternalBridge
{
if (IsLoggedIn)
{
- OnAnyRequest(container);
+ ExternalBridgeReceiverRequestReceivedEventArgs args = new ExternalBridgeReceiverRequestReceivedEventArgs();
+ args.Container = container;
+ ReceiverRequestReceived?.Invoke(this, args);
+
+ if (!args.Handled)
+ {
+ OnAnyRequest(container);
+ }
}
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
new file mode 100644
index 000000000..682de264c
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+
+namespace Tango.Integration.ExternalBridge
+{
+ public class ExternalBridgeReceiverRequestReceivedEventArgs
+ {
+ public MessageContainer Container { get; set; }
+ public bool Handled { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
new file mode 100644
index 000000000..c326c7dd7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+
+namespace Tango.Integration.ExternalBridge
+{
+ [AttributeUsage(AttributeTargets.Method)]
+ public class ExternalBridgeRequestHandlerMethodAttribute : Attribute
+ {
+ public Type Type { get; set; }
+
+ public ExternalBridgeRequestHandlerMethodAttribute(Type type)
+ {
+ Type = type;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
index 4395b5f41..ef98db11b 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
@@ -27,6 +27,8 @@ using Microsoft.AspNet.SignalR.Client;
using Tango.Integration.ExternalBridge.Web;
using Tango.Core.Threading;
using System.Diagnostics;
+using System.Reflection;
+using Newtonsoft.Json;
namespace Tango.Integration.ExternalBridge
{
@@ -41,6 +43,17 @@ namespace Tango.Integration.ExternalBridge
private IHubProxy _proxy;
private bool _isSignalRConnected;
private System.Timers.Timer _signalrPingTimer;
+ private Dictionary<String, RequestHandler> _requestHandlers;
+ private static JsonSerializerSettings _genericMessageSettings = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.All
+ };
+
+ private class RequestHandler
+ {
+ public IExternalBridgeRequestHandler Handler { get; set; }
+ public MethodInfo Method { get; set; }
+ }
#region Events
@@ -152,6 +165,8 @@ namespace Tango.Integration.ExternalBridge
/// </summary>
public ExternalBridgeService()
{
+ _requestHandlers = new Dictionary<string, RequestHandler>();
+
SignalRConfiguration = new ExternalBridgeSignalRConfiguration();
TcpTransportAdapterWriteMode = TcpTransportAdapterWriteMode.Interval;
@@ -239,6 +254,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest += Receiver_LoginRequest;
receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
receiver.Disconnected += Receiver_Disconnected;
+ receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
_receivers.Add(receiver);
await receiver.Connect();
}
@@ -255,6 +271,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest += Receiver_LoginRequest;
receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
receiver.Disconnected += Receiver_Disconnected;
+ receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
_receivers.Add(receiver);
await receiver.Connect();
}
@@ -309,6 +326,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest -= Receiver_LoginRequest;
receiver.ColorProfileRequest -= Receiver_ColorProfileRequest;
receiver.Disconnected -= Receiver_Disconnected;
+ receiver.ReceiverRequestReceived -= Receiver_ReceiverRequestReceived;
_receivers.Remove(receiver);
@@ -369,6 +387,62 @@ namespace Tango.Integration.ExternalBridge
}
}
+ private void Receiver_ReceiverRequestReceived(object sender, ExternalBridgeReceiverRequestReceivedEventArgs e)
+ {
+ if (e.Container.Type == MessageType.GenericRequest || _requestHandlers.ContainsKey(e.Container.Type.ToString()))
+ {
+ e.Handled = true;
+
+ ThreadFactory.StartNew(() =>
+ {
+ try
+ {
+ var message = MessageFactory.ExtractMessageFromContainer(e.Container);
+
+ if (e.Container.Type != MessageType.GenericRequest) //Handle standard PMR messages.
+ {
+ var handler = _requestHandlers[e.Container.Type.ToString()];
+ handler.Method.Invoke(handler.Handler, new object[]
+ {
+ message,
+ e.Container.Token,
+ sender,
+ });
+ }
+ else //Handle GenericRequest with inner JSON formated generic message.
+ {
+ var genericType = (message as GenericRequest).Type;
+
+ try
+ {
+ if (_requestHandlers.ContainsKey(genericType))
+ {
+ var json = (message as GenericRequest).Data.ToStringUtf8();
+ var innerMessage = JsonConvert.DeserializeObject(json, _genericMessageSettings);
+
+ var handler = _requestHandlers[genericType];
+ handler.Method.Invoke(handler.Handler, new object[]
+ {
+ innerMessage,
+ e.Container.Token,
+ sender,
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error invoking external bridge handler for request '{genericType}'.");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"An error occurred while trying or invoking an external bridge request handler for '{e.Container.Type}'.");
+ }
+ });
+ }
+ }
+
#endregion
#region Public Methods
@@ -598,5 +672,33 @@ namespace Tango.Integration.ExternalBridge
}
#endregion
+
+ #region Handlers Registration
+
+ public void RegisterRequestHandler(IExternalBridgeRequestHandler handler)
+ {
+ foreach (var method in handler.GetType().GetMethods())
+ {
+ var att = method.GetCustomAttribute<ExternalBridgeRequestHandlerMethodAttribute>();
+ if (att != null)
+ {
+ _requestHandlers.Add(att.Type.Name, new RequestHandler()
+ {
+ Handler = handler,
+ Method = method
+ });
+ }
+ }
+ }
+
+ public void UnregisterRequestHandler(IExternalBridgeRequestHandler handler)
+ {
+ foreach (var h in _requestHandlers.Where(x => x.Value.Handler == handler).ToList())
+ {
+ _requestHandlers.Remove(h.Key);
+ }
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
new file mode 100644
index 000000000..fe9e9caee
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
@@ -0,0 +1,14 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge
+{
+ public interface IExternalBridgeRequestHandler
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
index 7ae09c11d..e2d7bea30 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
@@ -1,4 +1,5 @@
-using System;
+using Google.Protobuf;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -83,5 +84,17 @@ namespace Tango.Integration.ExternalBridge
/// Disconnects the current remote client session.
/// </summary>
void DisconnectFullControlSession();
+
+ /// <summary>
+ /// Registers the request handler.
+ /// </summary>
+ /// <param name="handler">The handler.</param>
+ void RegisterRequestHandler(IExternalBridgeRequestHandler handler);
+
+ /// <summary>
+ /// Unregisters the request handler.
+ /// </summary>
+ /// <param name="handler">The handler.</param>
+ void UnregisterRequestHandler(IExternalBridgeRequestHandler handler);
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
index e2c799cf6..04b2903ce 100644
--- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
+++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
@@ -101,6 +101,9 @@
<Compile Include="ExternalBridge\ExternalBridgeClientConnectedEventArgs.cs" />
<Compile Include="ExternalBridge\ExternalBridgeReceiver.cs" />
<Compile Include="ExternalBridge\ExternalBridgeReceiverLoginRequestEventArgs.cs" />
+ <Compile Include="ExternalBridge\ExternalBridgeReceiverRequestReceivedEventArgs.cs" />
+ <Compile Include="ExternalBridge\ExternalBridgeRequestHandlerMethodAttribute.cs" />
+ <Compile Include="ExternalBridge\IExternalBridgeRequestHandler.cs" />
<Compile Include="ExternalBridge\ExternalBridgeSignalRConfiguration.cs" />
<Compile Include="ExternalBridge\ExternalBridgeSignalRClient.cs" />
<Compile Include="ExternalBridge\Web\MachineInfo.cs" />
diff --git a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs
index d50803fed..bc6c46a56 100644
--- a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs
+++ b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs
@@ -22,7 +22,7 @@ namespace Tango.PMR.Common {
static MessageTypeReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbirvNgoLTWVz",
+ "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiqaNwoLTWVz",
"c2FnZVR5cGUSCAoETm9uZRAAEhEKDUVycm9yUmVzcG9uc2UQARIUChBDYWxj",
"dWxhdGVSZXF1ZXN0EAMSFQoRQ2FsY3VsYXRlUmVzcG9uc2UQBBITCg9Qcm9n",
"cmVzc1JlcXVlc3QQBRIUChBQcm9ncmVzc1Jlc3BvbnNlEAYSHAoYU3R1YkNh",
@@ -101,85 +101,86 @@ namespace Tango.PMR.Common {
"cXVlc3QQ8wcSIAobU3RvcEFwcGxpY2F0aW9uTG9nc1Jlc3BvbnNlEPQHEhgK",
"E0NvbG9yUHJvZmlsZVJlcXVlc3QQ9QcSGQoUQ29sb3JQcm9maWxlUmVzcG9u",
"c2UQ9gcSGAoTVXBkYXRlU3RhdHVzUmVxdWVzdBD3BxIZChRVcGRhdGVTdGF0",
- "dXNSZXNwb25zZRD4BxIcChdTdGFydERpYWdub3N0aWNzUmVxdWVzdBDQDxId",
- "ChhTdGFydERpYWdub3N0aWNzUmVzcG9uc2UQ0Q8SHAoXTW90b3JBYm9ydEhv",
- "bWluZ1JlcXVlc3QQ0g8SHQoYTW90b3JBYm9ydEhvbWluZ1Jlc3BvbnNlENMP",
- "EhcKEk1vdG9ySG9taW5nUmVxdWVzdBDUDxIYChNNb3RvckhvbWluZ1Jlc3Bv",
- "bnNlENUPEhgKE01vdG9ySm9nZ2luZ1JlcXVlc3QQ1g8SGQoUTW90b3JKb2dn",
- "aW5nUmVzcG9uc2UQ1w8SHQoYTW90b3JBYm9ydEpvZ2dpbmdSZXF1ZXN0ENgP",
- "Eh4KGU1vdG9yQWJvcnRKb2dnaW5nUmVzcG9uc2UQ2Q8SIAobRGlzcGVuc2Vy",
- "QWJvcnRIb21pbmdSZXF1ZXN0ENoPEiEKHERpc3BlbnNlckFib3J0SG9taW5n",
- "UmVzcG9uc2UQ2w8SGwoWRGlzcGVuc2VySG9taW5nUmVxdWVzdBDcDxIcChdE",
- "aXNwZW5zZXJIb21pbmdSZXNwb25zZRDdDxIcChdEaXNwZW5zZXJKb2dnaW5n",
- "UmVxdWVzdBDeDxIdChhEaXNwZW5zZXJKb2dnaW5nUmVzcG9uc2UQ3w8SIQoc",
- "RGlzcGVuc2VyQWJvcnRKb2dnaW5nUmVxdWVzdBDgDxIiCh1EaXNwZW5zZXJB",
- "Ym9ydEpvZ2dpbmdSZXNwb25zZRDhDxIZChRTZXREaWdpdGFsT3V0UmVxdWVz",
- "dBDiDxIaChVTZXREaWdpdGFsT3V0UmVzcG9uc2UQ4w8SGQoUVGhyZWFkSm9n",
- "Z2luZ1JlcXVlc3QQ5A8SGgoVVGhyZWFkSm9nZ2luZ1Jlc3BvbnNlEOUPEh4K",
- "GVRocmVhZEFib3J0Sm9nZ2luZ1JlcXVlc3QQ5g8SHwoaVGhyZWFkQWJvcnRK",
- "b2dnaW5nUmVzcG9uc2UQ5w8SHQoYU2V0Q29tcG9uZW50VmFsdWVSZXF1ZXN0",
- "EOgPEh4KGVNldENvbXBvbmVudFZhbHVlUmVzcG9uc2UQ6Q8SGAoTUmVzb2x2",
- "ZUV2ZW50UmVxdWVzdBDqDxIZChRSZXNvbHZlRXZlbnRSZXNwb25zZRDrDxIb",
- "ChZTdG9wRGlhZ25vc3RpY3NSZXF1ZXN0EOwPEhwKF1N0b3BEaWFnbm9zdGlj",
- "c1Jlc3BvbnNlEO0PEiMKHlN0YXJ0RXZlbnRzTm90aWZpY2F0aW9uUmVxdWVz",
- "dBDuDxIkCh9TdGFydEV2ZW50c05vdGlmaWNhdGlvblJlc3BvbnNlEO8PEiIK",
- "HVN0b3BFdmVudHNOb3RpZmljYXRpb25SZXF1ZXN0EPAPEiMKHlN0b3BFdmVu",
- "dHNOb3RpZmljYXRpb25SZXNwb25zZRDxDxIaChVTZXRIZWF0ZXJTdGF0ZVJl",
- "cXVlc3QQ8g8SGwoWU2V0SGVhdGVyU3RhdGVSZXNwb25zZRDzDxIaChVTZXRC",
- "bG93ZXJTdGF0ZVJlcXVlc3QQ9A8SGwoWU2V0Qmxvd2VyU3RhdGVSZXNwb25z",
- "ZRD1DxIZChRTZXRWYWx2ZVN0YXRlUmVxdWVzdBD2DxIaChVTZXRWYWx2ZVN0",
- "YXRlUmVzcG9uc2UQ9w8SIQocU3RhcnRDYXJ0cmlkZ2VzVXBkYXRlUmVxdWVz",
- "dBD4DxIiCh1TdGFydENhcnRyaWRnZXNVcGRhdGVSZXNwb25zZRD5DxIgChtT",
- "dG9wQ2FydHJpZGdlc1VwZGF0ZVJlcXVlc3QQ+g8SIQocU3RvcENhcnRyaWRn",
- "ZXNVcGRhdGVSZXNwb25zZRD7DxIfChpDYXJ0cmlkZ2VWYWxpZGF0aW9uUmVx",
- "dWVzdBD8DxIgChtDYXJ0cmlkZ2VWYWxpZGF0aW9uUmVzcG9uc2UQ/Q8SDwoK",
- "Sm9iUmVxdWVzdBC4FxIQCgtKb2JSZXNwb25zZRC5FxIUCg9BYm9ydEpvYlJl",
- "cXVlc3QQuhcSFQoQQWJvcnRKb2JSZXNwb25zZRC7FxIjCh5VcGxvYWRQcm9j",
- "ZXNzUGFyYW1ldGVyc1JlcXVlc3QQvBcSJAofVXBsb2FkUHJvY2Vzc1BhcmFt",
- "ZXRlcnNSZXNwb25zZRC9FxIWChFDdXJyZW50Sm9iUmVxdWVzdBC+FxIXChJD",
- "dXJyZW50Sm9iUmVzcG9uc2UQvxcSHAoXUmVzdW1lQ3VycmVudEpvYlJlcXVl",
- "c3QQwBcSHQoYUmVzdW1lQ3VycmVudEpvYlJlc3BvbnNlEMEXEhkKFFN0YXJ0",
- "RGVidWdMb2dSZXF1ZXN0EKAfEhoKFVN0YXJ0RGVidWdMb2dSZXNwb25zZRCh",
- "HxIYChNTdG9wRGVidWdMb2dSZXF1ZXN0EKIfEhkKFFN0b3BEZWJ1Z0xvZ1Jl",
- "c3BvbnNlEKMfEh8KGlNldERlYnVnTG9nQ2F0ZWdvcnlSZXF1ZXN0EKQfEiAK",
- "G1NldERlYnVnTG9nQ2F0ZWdvcnlSZXNwb25zZRClHxIhChxTZXR1cERlYnVn",
- "RGlzcmlidXRvcnNSZXF1ZXN0EKYfEiIKHVNldHVwRGVidWdEaXNyaWJ1dG9y",
- "c1Jlc3BvbnNlEKcfEicKIlVwbG9hZEhhcmR3YXJlQ29uZmlndXJhdGlvblJl",
- "cXVlc3QQiCcSKAojVXBsb2FkSGFyZHdhcmVDb25maWd1cmF0aW9uUmVzcG9u",
- "c2UQiScSFwoSU3lzdGVtUmVzZXRSZXF1ZXN0EIonEhgKE1N5c3RlbVJlc2V0",
- "UmVzcG9uc2UQiycSFQoQS2VlcEFsaXZlUmVxdWVzdBDwLhIWChFLZWVwQWxp",
- "dmVSZXNwb25zZRDxLhITCg5Db25uZWN0UmVxdWVzdBDyLhIUCg9Db25uZWN0",
- "UmVzcG9uc2UQ8y4SFgoRRGlzY29ubmVjdFJlcXVlc3QQ9C4SFwoSRGlzY29u",
- "bmVjdFJlc3BvbnNlEPUuEhYKEUZpbGVVcGxvYWRSZXF1ZXN0ENg2EhcKEkZp",
- "bGVVcGxvYWRSZXNwb25zZRDZNhIbChZGaWxlQ2h1bmtVcGxvYWRSZXF1ZXN0",
- "ENo2EhwKF0ZpbGVDaHVua1VwbG9hZFJlc3BvbnNlENs2EhoKFUV4ZWN1dGVQ",
- "cm9jZXNzUmVxdWVzdBDcNhIbChZFeGVjdXRlUHJvY2Vzc1Jlc3BvbnNlEN02",
- "EhcKEktpbGxQcm9jZXNzUmVxdWVzdBDeNhIYChNLaWxsUHJvY2Vzc1Jlc3Bv",
- "bnNlEN82EhIKDUNyZWF0ZVJlcXVlc3QQ4DYSEwoOQ3JlYXRlUmVzcG9uc2UQ",
- "4TYSEgoNRGVsZXRlUmVxdWVzdBDiNhITCg5EZWxldGVSZXNwb25zZRDjNhIa",
- "ChVHZXRTdG9yYWdlSW5mb1JlcXVlc3QQ5DYSGwoWR2V0U3RvcmFnZUluZm9S",
- "ZXNwb25zZRDlNhIUCg9HZXRGaWxlc1JlcXVlc3QQ5jYSFQoQR2V0RmlsZXNS",
- "ZXNwb25zZRDnNhIYChNGaWxlRG93bmxvYWRSZXF1ZXN0EOg2EhkKFEZpbGVE",
- "b3dubG9hZFJlc3BvbnNlEOk2Eh0KGEZpbGVDaHVua0Rvd25sb2FkUmVxdWVz",
- "dBDqNhIeChlGaWxlQ2h1bmtEb3dubG9hZFJlc3BvbnNlEOs2EhsKFlZhbGlk",
- "YXRlVmVyc2lvblJlcXVlc3QQ7DYSHAoXVmFsaWRhdGVWZXJzaW9uUmVzcG9u",
- "c2UQ7TYSGwoWQWN0aXZhdGVWZXJzaW9uUmVxdWVzdBDuNhIcChdBY3RpdmF0",
- "ZVZlcnNpb25SZXNwb25zZRDvNhIZChREaXNwZW5zZXJEYXRhUmVxdWVzdBDA",
- "PhIaChVEaXNwZW5zZXJEYXRhUmVzcG9uc2UQwT4SHAoXTWlkVGFua0RhdGFT",
- "ZXR1cFJlcXVlc3QQwj4SHQoYTWlkVGFua0RhdGFTZXR1cFJlc3BvbnNlEMM+",
- "EiIKHU1hY2hpbmVDYWxpYnJhdGlvbkRhdGFSZXF1ZXN0EMQ+EiMKHk1hY2hp",
- "bmVDYWxpYnJhdGlvbkRhdGFSZXNwb25zZRDFPhIkCh9TdGFydE1hY2hpbmVT",
- "dGF0dXNVcGRhdGVSZXF1ZXN0EKhGEiUKIFN0YXJ0TWFjaGluZVN0YXR1c1Vw",
- "ZGF0ZVJlc3BvbnNlEKlGEiMKHlN0b3BNYWNoaW5lU3RhdHVzVXBkYXRlUmVx",
- "dWVzdBCqRhIkCh9TdG9wTWFjaGluZVN0YXR1c1VwZGF0ZVJlc3BvbnNlEKtG",
- "EhoKFVN0YXJ0UG93ZXJEb3duUmVxdWVzdBCQThIbChZTdGFydFBvd2VyRG93",
- "blJlc3BvbnNlEJFOEhoKFUFib3J0UG93ZXJEb3duUmVxdWVzdBCSThIbChZB",
- "Ym9ydFBvd2VyRG93blJlc3BvbnNlEJNOEh4KGVN0YXJ0VGhyZWFkTG9hZGlu",
- "Z1JlcXVlc3QQ+FUSHwoaU3RhcnRUaHJlYWRMb2FkaW5nUmVzcG9uc2UQ+VUS",
- "IQocQ29udGludWVUaHJlYWRMb2FkaW5nUmVxdWVzdBD6VRIiCh1Db250aW51",
- "ZVRocmVhZExvYWRpbmdSZXNwb25zZRD7VRIdChhTdG9wVGhyZWFkTG9hZGlu",
- "Z1JlcXVlc3QQ/FUSHgoZU3RvcFRocmVhZExvYWRpbmdSZXNwb25zZRD9VUIc",
- "Chpjb20udHdpbmUudGFuZ28ucG1yLmNvbW1vbmIGcHJvdG8z"));
+ "dXNSZXNwb25zZRD4BxITCg5HZW5lcmljUmVxdWVzdBD5BxIUCg9HZW5lcmlj",
+ "UmVzcG9uc2UQ+gcSHAoXU3RhcnREaWFnbm9zdGljc1JlcXVlc3QQ0A8SHQoY",
+ "U3RhcnREaWFnbm9zdGljc1Jlc3BvbnNlENEPEhwKF01vdG9yQWJvcnRIb21p",
+ "bmdSZXF1ZXN0ENIPEh0KGE1vdG9yQWJvcnRIb21pbmdSZXNwb25zZRDTDxIX",
+ "ChJNb3RvckhvbWluZ1JlcXVlc3QQ1A8SGAoTTW90b3JIb21pbmdSZXNwb25z",
+ "ZRDVDxIYChNNb3RvckpvZ2dpbmdSZXF1ZXN0ENYPEhkKFE1vdG9ySm9nZ2lu",
+ "Z1Jlc3BvbnNlENcPEh0KGE1vdG9yQWJvcnRKb2dnaW5nUmVxdWVzdBDYDxIe",
+ "ChlNb3RvckFib3J0Sm9nZ2luZ1Jlc3BvbnNlENkPEiAKG0Rpc3BlbnNlckFi",
+ "b3J0SG9taW5nUmVxdWVzdBDaDxIhChxEaXNwZW5zZXJBYm9ydEhvbWluZ1Jl",
+ "c3BvbnNlENsPEhsKFkRpc3BlbnNlckhvbWluZ1JlcXVlc3QQ3A8SHAoXRGlz",
+ "cGVuc2VySG9taW5nUmVzcG9uc2UQ3Q8SHAoXRGlzcGVuc2VySm9nZ2luZ1Jl",
+ "cXVlc3QQ3g8SHQoYRGlzcGVuc2VySm9nZ2luZ1Jlc3BvbnNlEN8PEiEKHERp",
+ "c3BlbnNlckFib3J0Sm9nZ2luZ1JlcXVlc3QQ4A8SIgodRGlzcGVuc2VyQWJv",
+ "cnRKb2dnaW5nUmVzcG9uc2UQ4Q8SGQoUU2V0RGlnaXRhbE91dFJlcXVlc3QQ",
+ "4g8SGgoVU2V0RGlnaXRhbE91dFJlc3BvbnNlEOMPEhkKFFRocmVhZEpvZ2dp",
+ "bmdSZXF1ZXN0EOQPEhoKFVRocmVhZEpvZ2dpbmdSZXNwb25zZRDlDxIeChlU",
+ "aHJlYWRBYm9ydEpvZ2dpbmdSZXF1ZXN0EOYPEh8KGlRocmVhZEFib3J0Sm9n",
+ "Z2luZ1Jlc3BvbnNlEOcPEh0KGFNldENvbXBvbmVudFZhbHVlUmVxdWVzdBDo",
+ "DxIeChlTZXRDb21wb25lbnRWYWx1ZVJlc3BvbnNlEOkPEhgKE1Jlc29sdmVF",
+ "dmVudFJlcXVlc3QQ6g8SGQoUUmVzb2x2ZUV2ZW50UmVzcG9uc2UQ6w8SGwoW",
+ "U3RvcERpYWdub3N0aWNzUmVxdWVzdBDsDxIcChdTdG9wRGlhZ25vc3RpY3NS",
+ "ZXNwb25zZRDtDxIjCh5TdGFydEV2ZW50c05vdGlmaWNhdGlvblJlcXVlc3QQ",
+ "7g8SJAofU3RhcnRFdmVudHNOb3RpZmljYXRpb25SZXNwb25zZRDvDxIiCh1T",
+ "dG9wRXZlbnRzTm90aWZpY2F0aW9uUmVxdWVzdBDwDxIjCh5TdG9wRXZlbnRz",
+ "Tm90aWZpY2F0aW9uUmVzcG9uc2UQ8Q8SGgoVU2V0SGVhdGVyU3RhdGVSZXF1",
+ "ZXN0EPIPEhsKFlNldEhlYXRlclN0YXRlUmVzcG9uc2UQ8w8SGgoVU2V0Qmxv",
+ "d2VyU3RhdGVSZXF1ZXN0EPQPEhsKFlNldEJsb3dlclN0YXRlUmVzcG9uc2UQ",
+ "9Q8SGQoUU2V0VmFsdmVTdGF0ZVJlcXVlc3QQ9g8SGgoVU2V0VmFsdmVTdGF0",
+ "ZVJlc3BvbnNlEPcPEiEKHFN0YXJ0Q2FydHJpZGdlc1VwZGF0ZVJlcXVlc3QQ",
+ "+A8SIgodU3RhcnRDYXJ0cmlkZ2VzVXBkYXRlUmVzcG9uc2UQ+Q8SIAobU3Rv",
+ "cENhcnRyaWRnZXNVcGRhdGVSZXF1ZXN0EPoPEiEKHFN0b3BDYXJ0cmlkZ2Vz",
+ "VXBkYXRlUmVzcG9uc2UQ+w8SHwoaQ2FydHJpZGdlVmFsaWRhdGlvblJlcXVl",
+ "c3QQ/A8SIAobQ2FydHJpZGdlVmFsaWRhdGlvblJlc3BvbnNlEP0PEg8KCkpv",
+ "YlJlcXVlc3QQuBcSEAoLSm9iUmVzcG9uc2UQuRcSFAoPQWJvcnRKb2JSZXF1",
+ "ZXN0ELoXEhUKEEFib3J0Sm9iUmVzcG9uc2UQuxcSIwoeVXBsb2FkUHJvY2Vz",
+ "c1BhcmFtZXRlcnNSZXF1ZXN0ELwXEiQKH1VwbG9hZFByb2Nlc3NQYXJhbWV0",
+ "ZXJzUmVzcG9uc2UQvRcSFgoRQ3VycmVudEpvYlJlcXVlc3QQvhcSFwoSQ3Vy",
+ "cmVudEpvYlJlc3BvbnNlEL8XEhwKF1Jlc3VtZUN1cnJlbnRKb2JSZXF1ZXN0",
+ "EMAXEh0KGFJlc3VtZUN1cnJlbnRKb2JSZXNwb25zZRDBFxIZChRTdGFydERl",
+ "YnVnTG9nUmVxdWVzdBCgHxIaChVTdGFydERlYnVnTG9nUmVzcG9uc2UQoR8S",
+ "GAoTU3RvcERlYnVnTG9nUmVxdWVzdBCiHxIZChRTdG9wRGVidWdMb2dSZXNw",
+ "b25zZRCjHxIfChpTZXREZWJ1Z0xvZ0NhdGVnb3J5UmVxdWVzdBCkHxIgChtT",
+ "ZXREZWJ1Z0xvZ0NhdGVnb3J5UmVzcG9uc2UQpR8SIQocU2V0dXBEZWJ1Z0Rp",
+ "c3JpYnV0b3JzUmVxdWVzdBCmHxIiCh1TZXR1cERlYnVnRGlzcmlidXRvcnNS",
+ "ZXNwb25zZRCnHxInCiJVcGxvYWRIYXJkd2FyZUNvbmZpZ3VyYXRpb25SZXF1",
+ "ZXN0EIgnEigKI1VwbG9hZEhhcmR3YXJlQ29uZmlndXJhdGlvblJlc3BvbnNl",
+ "EIknEhcKElN5c3RlbVJlc2V0UmVxdWVzdBCKJxIYChNTeXN0ZW1SZXNldFJl",
+ "c3BvbnNlEIsnEhUKEEtlZXBBbGl2ZVJlcXVlc3QQ8C4SFgoRS2VlcEFsaXZl",
+ "UmVzcG9uc2UQ8S4SEwoOQ29ubmVjdFJlcXVlc3QQ8i4SFAoPQ29ubmVjdFJl",
+ "c3BvbnNlEPMuEhYKEURpc2Nvbm5lY3RSZXF1ZXN0EPQuEhcKEkRpc2Nvbm5l",
+ "Y3RSZXNwb25zZRD1LhIWChFGaWxlVXBsb2FkUmVxdWVzdBDYNhIXChJGaWxl",
+ "VXBsb2FkUmVzcG9uc2UQ2TYSGwoWRmlsZUNodW5rVXBsb2FkUmVxdWVzdBDa",
+ "NhIcChdGaWxlQ2h1bmtVcGxvYWRSZXNwb25zZRDbNhIaChVFeGVjdXRlUHJv",
+ "Y2Vzc1JlcXVlc3QQ3DYSGwoWRXhlY3V0ZVByb2Nlc3NSZXNwb25zZRDdNhIX",
+ "ChJLaWxsUHJvY2Vzc1JlcXVlc3QQ3jYSGAoTS2lsbFByb2Nlc3NSZXNwb25z",
+ "ZRDfNhISCg1DcmVhdGVSZXF1ZXN0EOA2EhMKDkNyZWF0ZVJlc3BvbnNlEOE2",
+ "EhIKDURlbGV0ZVJlcXVlc3QQ4jYSEwoORGVsZXRlUmVzcG9uc2UQ4zYSGgoV",
+ "R2V0U3RvcmFnZUluZm9SZXF1ZXN0EOQ2EhsKFkdldFN0b3JhZ2VJbmZvUmVz",
+ "cG9uc2UQ5TYSFAoPR2V0RmlsZXNSZXF1ZXN0EOY2EhUKEEdldEZpbGVzUmVz",
+ "cG9uc2UQ5zYSGAoTRmlsZURvd25sb2FkUmVxdWVzdBDoNhIZChRGaWxlRG93",
+ "bmxvYWRSZXNwb25zZRDpNhIdChhGaWxlQ2h1bmtEb3dubG9hZFJlcXVlc3QQ",
+ "6jYSHgoZRmlsZUNodW5rRG93bmxvYWRSZXNwb25zZRDrNhIbChZWYWxpZGF0",
+ "ZVZlcnNpb25SZXF1ZXN0EOw2EhwKF1ZhbGlkYXRlVmVyc2lvblJlc3BvbnNl",
+ "EO02EhsKFkFjdGl2YXRlVmVyc2lvblJlcXVlc3QQ7jYSHAoXQWN0aXZhdGVW",
+ "ZXJzaW9uUmVzcG9uc2UQ7zYSGQoURGlzcGVuc2VyRGF0YVJlcXVlc3QQwD4S",
+ "GgoVRGlzcGVuc2VyRGF0YVJlc3BvbnNlEME+EhwKF01pZFRhbmtEYXRhU2V0",
+ "dXBSZXF1ZXN0EMI+Eh0KGE1pZFRhbmtEYXRhU2V0dXBSZXNwb25zZRDDPhIi",
+ "Ch1NYWNoaW5lQ2FsaWJyYXRpb25EYXRhUmVxdWVzdBDEPhIjCh5NYWNoaW5l",
+ "Q2FsaWJyYXRpb25EYXRhUmVzcG9uc2UQxT4SJAofU3RhcnRNYWNoaW5lU3Rh",
+ "dHVzVXBkYXRlUmVxdWVzdBCoRhIlCiBTdGFydE1hY2hpbmVTdGF0dXNVcGRh",
+ "dGVSZXNwb25zZRCpRhIjCh5TdG9wTWFjaGluZVN0YXR1c1VwZGF0ZVJlcXVl",
+ "c3QQqkYSJAofU3RvcE1hY2hpbmVTdGF0dXNVcGRhdGVSZXNwb25zZRCrRhIa",
+ "ChVTdGFydFBvd2VyRG93blJlcXVlc3QQkE4SGwoWU3RhcnRQb3dlckRvd25S",
+ "ZXNwb25zZRCRThIaChVBYm9ydFBvd2VyRG93blJlcXVlc3QQkk4SGwoWQWJv",
+ "cnRQb3dlckRvd25SZXNwb25zZRCTThIeChlTdGFydFRocmVhZExvYWRpbmdS",
+ "ZXF1ZXN0EPhVEh8KGlN0YXJ0VGhyZWFkTG9hZGluZ1Jlc3BvbnNlEPlVEiEK",
+ "HENvbnRpbnVlVGhyZWFkTG9hZGluZ1JlcXVlc3QQ+lUSIgodQ29udGludWVU",
+ "aHJlYWRMb2FkaW5nUmVzcG9uc2UQ+1USHQoYU3RvcFRocmVhZExvYWRpbmdS",
+ "ZXF1ZXN0EPxVEh4KGVN0b3BUaHJlYWRMb2FkaW5nUmVzcG9uc2UQ/VVCHAoa",
+ "Y29tLnR3aW5lLnRhbmdvLnBtci5jb21tb25iBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null));
@@ -325,6 +326,8 @@ namespace Tango.PMR.Common {
[pbr::OriginalName("ColorProfileResponse")] ColorProfileResponse = 1014,
[pbr::OriginalName("UpdateStatusRequest")] UpdateStatusRequest = 1015,
[pbr::OriginalName("UpdateStatusResponse")] UpdateStatusResponse = 1016,
+ [pbr::OriginalName("GenericRequest")] GenericRequest = 1017,
+ [pbr::OriginalName("GenericResponse")] GenericResponse = 1018,
/// <summary>
///Diagnostics
/// </summary>
diff --git a/Software/Visual_Studio/Tango.PMR/Integration/GenericRequest.cs b/Software/Visual_Studio/Tango.PMR/Integration/GenericRequest.cs
new file mode 100644
index 000000000..ff158a455
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Integration/GenericRequest.cs
@@ -0,0 +1,187 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: GenericRequest.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Integration {
+
+ /// <summary>Holder for reflection information generated from GenericRequest.proto</summary>
+ public static partial class GenericRequestReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for GenericRequest.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static GenericRequestReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChRHZW5lcmljUmVxdWVzdC5wcm90bxIVVGFuZ28uUE1SLkludGVncmF0aW9u",
+ "IiwKDkdlbmVyaWNSZXF1ZXN0EgwKBFR5cGUYASABKAkSDAoERGF0YRgCIAEo",
+ "DEIhCh9jb20udHdpbmUudGFuZ28ucG1yLmludGVncmF0aW9uYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Integration.GenericRequest), global::Tango.PMR.Integration.GenericRequest.Parser, new[]{ "Type", "Data" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class GenericRequest : pb::IMessage<GenericRequest> {
+ private static readonly pb::MessageParser<GenericRequest> _parser = new pb::MessageParser<GenericRequest>(() => new GenericRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<GenericRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Integration.GenericRequestReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericRequest(GenericRequest other) : this() {
+ type_ = other.type_;
+ data_ = other.data_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericRequest Clone() {
+ return new GenericRequest(this);
+ }
+
+ /// <summary>Field number for the "Type" field.</summary>
+ public const int TypeFieldNumber = 1;
+ private string type_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Type {
+ get { return type_; }
+ set {
+ type_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "Data" field.</summary>
+ public const int DataFieldNumber = 2;
+ private pb::ByteString data_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString Data {
+ get { return data_; }
+ set {
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as GenericRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(GenericRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Type != other.Type) return false;
+ if (Data != other.Data) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Type.Length != 0) hash ^= Type.GetHashCode();
+ if (Data.Length != 0) hash ^= Data.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Type.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Type);
+ }
+ if (Data.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteBytes(Data);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Type.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Type);
+ }
+ if (Data.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(GenericRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Type.Length != 0) {
+ Type = other.Type;
+ }
+ if (other.Data.Length != 0) {
+ Data = other.Data;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Type = input.ReadString();
+ break;
+ }
+ case 18: {
+ Data = input.ReadBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Integration/GenericResponse.cs b/Software/Visual_Studio/Tango.PMR/Integration/GenericResponse.cs
new file mode 100644
index 000000000..9262b530a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Integration/GenericResponse.cs
@@ -0,0 +1,159 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: GenericResponse.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Integration {
+
+ /// <summary>Holder for reflection information generated from GenericResponse.proto</summary>
+ public static partial class GenericResponseReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for GenericResponse.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static GenericResponseReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChVHZW5lcmljUmVzcG9uc2UucHJvdG8SFVRhbmdvLlBNUi5JbnRlZ3JhdGlv",
+ "biIfCg9HZW5lcmljUmVzcG9uc2USDAoERGF0YRgCIAEoDEIhCh9jb20udHdp",
+ "bmUudGFuZ28ucG1yLmludGVncmF0aW9uYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Integration.GenericResponse), global::Tango.PMR.Integration.GenericResponse.Parser, new[]{ "Data" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class GenericResponse : pb::IMessage<GenericResponse> {
+ private static readonly pb::MessageParser<GenericResponse> _parser = new pb::MessageParser<GenericResponse>(() => new GenericResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<GenericResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Integration.GenericResponseReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericResponse(GenericResponse other) : this() {
+ data_ = other.data_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GenericResponse Clone() {
+ return new GenericResponse(this);
+ }
+
+ /// <summary>Field number for the "Data" field.</summary>
+ public const int DataFieldNumber = 2;
+ private pb::ByteString data_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString Data {
+ get { return data_; }
+ set {
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as GenericResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(GenericResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Data != other.Data) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Data.Length != 0) hash ^= Data.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Data.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteBytes(Data);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Data.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(GenericResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Data.Length != 0) {
+ Data = other.Data;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 18: {
+ Data = input.ReadBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
index 3dd9d7f48..d7b2203dd 100644
--- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
+++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
@@ -214,6 +214,8 @@
<Compile Include="Integration\ExternalBridgeLogoutRequest.cs" />
<Compile Include="Integration\ExternalBridgeLogoutResponse.cs" />
<Compile Include="Integration\ExternalBridgeUdpDiscoveryPacket.cs" />
+ <Compile Include="Integration\GenericRequest.cs" />
+ <Compile Include="Integration\GenericResponse.cs" />
<Compile Include="Integration\OverrideDataBaseRequest.cs" />
<Compile Include="Integration\OverrideDataBaseResponse.cs" />
<Compile Include="Integration\StartApplicationLogsRequest.cs" />
diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs
index 5576de0b2..bffcb0444 100644
--- a/Software/Visual_Studio/Tango.Transport/ITransporter.cs
+++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs
@@ -84,6 +84,26 @@ namespace Tango.Transport
IObservable<TangoMessage<Response>> SendContinuousRequest<Request, Response>(TangoMessage<Request> request, TransportContinuousRequestConfig config = null) where Request : IMessage<Request> where Response : IMessage<Response>;
/// <summary>
+ /// Sends a generic request of any type.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="config">The configuration.</param>
+ /// <returns></returns>
+ Task<Response> SendGenericRequest<Request, Response>(Request request, TransportRequestConfig config = null) where Request : class where Response : class;
+
+ /// <summary>
+ /// Sends a generic response.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <param name="token">The request token.</param>
+ /// <param name="config">The response configuration.</param>
+ /// <returns></returns>
+ Task SendGenericResponse<Response>(Response response, String token, TransportResponseConfig config = null) where Response : class;
+
+ /// <summary>
/// Sends the response.
/// </summary>
/// <param name="container">The container.</param>
diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
index edd70f22f..e0f9d46dd 100644
--- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
+++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
@@ -19,6 +19,8 @@ using Tango.PMR.Connection;
using Tango.Core.Threading;
using System.IO;
using Tango.Core.ExtensionMethods;
+using Tango.PMR.Integration;
+using Newtonsoft.Json;
namespace Tango.Transport
{
@@ -40,6 +42,10 @@ namespace Tango.Transport
private ITransportAdapter _adapter;
private Dictionary<String, PendingResponse> _pendingResponses;
private DateTime _lastKeepAliveTime;
+ private static JsonSerializerSettings _genericMessageSettings = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.All,
+ };
#region Events
@@ -840,6 +846,39 @@ namespace Tango.Transport
return subject.AsObservable();
}
+ /// <summary>
+ /// Sends a generic request of any type.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="config">The configuration.</param>
+ /// <returns></returns>
+ public async Task<Response> SendGenericRequest<Request, Response>(Request request, TransportRequestConfig config = null) where Request : class where Response : class
+ {
+ GenericRequest genericRequest = new GenericRequest();
+ genericRequest.Type = request.GetType().Name;
+ genericRequest.Data = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(request, _genericMessageSettings));
+ var response = await SendRequest<GenericRequest, GenericResponse>(genericRequest, config);
+ var responseObject = JsonConvert.DeserializeObject<Response>(response.Message.Data.ToStringUtf8());
+ return responseObject;
+ }
+
+ /// <summary>
+ /// Sends a generic response.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <param name="token">The request token.</param>
+ /// <param name="config">The response configuration.</param>
+ /// <returns></returns>
+ public async Task SendGenericResponse<Response>(Response response, String token, TransportResponseConfig config = null) where Response : class
+ {
+ GenericResponse genericResponse = new GenericResponse();
+ genericResponse.Data = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(response, _genericMessageSettings));
+ await SendResponse<GenericResponse>(genericResponse, token, config);
+ }
+
#endregion
#region Public Response Methods