aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2017-11-09 20:26:27 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2017-11-09 20:26:27 +0200
commit070aa53b6763fd2b5f7b482bf0f5070711f91ef6 (patch)
treefcd654e68ba229d093d07c0c261044ff80d5beaf
parent6626d0227c28c0a9f990e08c431e8b80739ea58d (diff)
downloadTango-070aa53b6763fd2b5f7b482bf0f5070711f91ef6.tar.gz
Tango-070aa53b6763fd2b5f7b482bf0f5070711f91ef6.zip
Working on Tango integration & emulation on C# side.
-rw-r--r--Software/PMR/Messages/Common/MessageType.proto2
-rw-r--r--Software/PMR/Messages/Stubs/Stub1.proto15
-rw-r--r--Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.Emulator/App.config6
-rw-r--r--Software/Visual Studio/Tango.Emulator/App.xaml20
-rw-r--r--Software/Visual Studio/Tango.Emulator/App.xaml.cs17
-rw-r--r--Software/Visual Studio/Tango.Emulator/Images/machine-trans.pngbin0 -> 45618 bytes
-rw-r--r--Software/Visual Studio/Tango.Emulator/Images/phone.pngbin0 -> 72384 bytes
-rw-r--r--Software/Visual Studio/Tango.Emulator/MainWindow.xaml95
-rw-r--r--Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs177
-rw-r--r--Software/Visual Studio/Tango.Emulator/Models/StubVM.cs16
-rw-r--r--Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual Studio/Tango.Emulator/Properties/Resources.resx117
-rw-r--r--Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual Studio/Tango.Emulator/Properties/Settings.settings7
-rw-r--r--Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj162
-rw-r--r--Software/Visual Studio/Tango.Emulator/packages.config12
-rw-r--r--Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs20
-rw-r--r--Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs187
-rw-r--r--Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs131
-rw-r--r--Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs19
-rw-r--r--Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs122
-rw-r--r--Software/Visual Studio/Tango.Integration/Tango.Integration.csproj105
-rw-r--r--Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs66
-rw-r--r--Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs33
-rw-r--r--Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs255
-rw-r--r--Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs17
-rw-r--r--Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs17
-rw-r--r--Software/Visual Studio/Tango.Integration/packages.config10
-rw-r--r--Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs41
-rw-r--r--Software/Visual Studio/Tango.PMR/Common/MessageType.cs9
-rw-r--r--Software/Visual Studio/Tango.PMR/Common/RGB.cs3
-rw-r--r--Software/Visual Studio/Tango.PMR/Jobs/Job.cs3
-rw-r--r--Software/Visual Studio/Tango.PMR/Jobs/Segment.cs3
-rw-r--r--Software/Visual Studio/Tango.PMR/MessageFactory.cs44
-rw-r--r--Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs305
-rw-r--r--Software/Visual Studio/Tango.PMR/Tango.PMR.csproj1
-rw-r--r--Software/Visual Studio/Tango.PMR/TangoMessage.cs15
-rw-r--r--Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Tango.sln12
-rw-r--r--Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs4
-rw-r--r--Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs2
49 files changed, 2171 insertions, 26 deletions
diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto
index f1a284679..857e6874c 100644
--- a/Software/PMR/Messages/Common/MessageType.proto
+++ b/Software/PMR/Messages/Common/MessageType.proto
@@ -8,4 +8,6 @@ enum MessageType
RGB = 0;
Job = 1;
Segment = 2;
+ Stub1Request = 3;
+ Stub1Response = 4;
}
diff --git a/Software/PMR/Messages/Stubs/Stub1.proto b/Software/PMR/Messages/Stubs/Stub1.proto
new file mode 100644
index 000000000..e202613ff
--- /dev/null
+++ b/Software/PMR/Messages/Stubs/Stub1.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package Tango.PMR.Stubs;
+option java_package = "com.twine.tango.pmr.stubs";
+
+message Stub1Request
+{
+ int32 A = 1;
+ int32 B = 2;
+}
+
+message Stub1Response
+{
+ int32 Sum = 1;
+} \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs
index f76af4bb8..577126b91 100644
--- a/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Core Components")]
+[assembly: AssemblyTitle("Tango - Core Components")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/App.config b/Software/Visual Studio/Tango.Emulator/App.config
new file mode 100644
index 000000000..8e1564635
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+ </startup>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/App.xaml b/Software/Visual Studio/Tango.Emulator/App.xaml
new file mode 100644
index 000000000..a5bc9bfe1
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/App.xaml
@@ -0,0 +1,20 @@
+<Application x:Class="Tango.Emulator.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.Emulator"
+ StartupUri="MainWindow.xaml">
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
+ <!-- Accent and AppTheme setting -->
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Red.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
diff --git a/Software/Visual Studio/Tango.Emulator/App.xaml.cs b/Software/Visual Studio/Tango.Emulator/App.xaml.cs
new file mode 100644
index 000000000..ca571bda0
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.Emulator
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+ }
+}
diff --git a/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png b/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png
new file mode 100644
index 000000000..a7cf65852
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png
Binary files differ
diff --git a/Software/Visual Studio/Tango.Emulator/Images/phone.png b/Software/Visual Studio/Tango.Emulator/Images/phone.png
new file mode 100644
index 000000000..d93503adc
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Images/phone.png
Binary files differ
diff --git a/Software/Visual Studio/Tango.Emulator/MainWindow.xaml b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml
new file mode 100644
index 000000000..f5e4ee98e
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml
@@ -0,0 +1,95 @@
+<mahapps:MetroWindow x:Class="Tango.Emulator.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.Emulator"
+ mc:Ignorable="d"
+ Title="Tango Machine Emulator" Height="720" Width="1200" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}">
+ <Grid>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="100"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20 15">
+ <Image Source="Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Text="Tango Machine Emulator" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36" Foreground="Yellow">
+ <TextBlock.Effect>
+ <DropShadowEffect/>
+ </TextBlock.Effect>
+ </TextBlock>
+ </StackPanel>
+
+ <Rectangle VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="20 0 50 0" Stroke="DimGray" StrokeThickness="1" StrokeDashArray="5"></Rectangle>
+ </Grid>
+
+ <Grid Grid.Row="1" Margin="20">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="70"/>
+ </Grid.RowDefinitions>
+
+ <Grid x:Name="gridContent" Background="#151515" Margin="5">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="300"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Image Source="Images/phone.png" RenderOptions.BitmapScalingMode="Fant" Stretch="Fill"></Image>
+
+ <Grid Margin="45 70 45 55">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="302*"/>
+ <RowDefinition Height="35"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <Button Width="100" Height="40" Click="Button_Click">SEND</Button>
+ </Grid>
+
+ <UniformGrid Grid.Row="1" Columns="2" Background="#151515">
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding DisconnectCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Unlink" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Disconnect</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ConnectCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Link" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Connect</TextBlock>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
+ </Grid>
+ </Grid>
+ <Grid x:Name="gridActions" Grid.Row="1" Background="#151515" Margin="5">
+ <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Margin="5">
+ <Button Margin="5" MinWidth="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StopCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Stop" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">STOP</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Margin="5" MinWidth="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StartCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Play" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">START</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs
new file mode 100644
index 000000000..43e3563bf
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs
@@ -0,0 +1,177 @@
+using MahApps.Metro.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Tango.Integration.Adapters;
+using Tango.Integration.Emulators;
+using Tango.Integration.TCP;
+using Tango.Integration.Transport;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Stubs;
+using Tango.SharedUI.Commands;
+
+namespace Tango.Emulator
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : MetroWindow
+ {
+ private ProtoTransporter mobileTransporter;
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the emulator is started.
+ /// </summary>
+ public bool IsStarted
+ {
+ get { return (bool)GetValue(IsStartedProperty); }
+ set { SetValue(IsStartedProperty, value); }
+ }
+ public static readonly DependencyProperty IsStartedProperty =
+ DependencyProperty.Register("IsStarted", typeof(bool), typeof(MainWindow), new PropertyMetadata(false));
+
+ /// <summary>
+ /// Gets or sets the emulator.
+ /// </summary>
+ public MachineEmulator Emulator
+ {
+ get { return (MachineEmulator)GetValue(EmulatorProperty); }
+ set { SetValue(EmulatorProperty, value); }
+ }
+ public static readonly DependencyProperty EmulatorProperty =
+ DependencyProperty.Register("Emulator", typeof(MachineEmulator), typeof(MainWindow), new PropertyMetadata(null));
+
+
+ /// <summary>
+ /// Gets or sets the TCP server.
+ /// </summary>
+ public TcpServer TcpServer
+ {
+ get { return (TcpServer)GetValue(TcpServerProperty); }
+ set { SetValue(TcpServerProperty, value); }
+ }
+ public static readonly DependencyProperty TcpServerProperty =
+ DependencyProperty.Register("TcpServer", typeof(TcpServer), typeof(MainWindow), new PropertyMetadata(null));
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the start command.
+ /// </summary>
+ public RelayCommand StartCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop command.
+ /// </summary>
+ public RelayCommand StopCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the connect command.
+ /// </summary>
+ public RelayCommand ConnectCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the disconnect command.
+ /// </summary>
+ public RelayCommand DisconnectCommand { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainWindow"/> class.
+ /// </summary>
+ public MainWindow()
+ {
+ LogManager.RegisterLogger(new VSOutputLogger());
+
+ TcpServer = new TcpServer(9999);
+ TcpServer.ClientConnected += TcpServer_ClientConnected;
+
+ mobileTransporter = new ProtoTransporter();
+
+ StartCommand = new RelayCommand(() =>
+ {
+ TcpServer.Start();
+ StopCommand.RaiseCanExecuteChanged();
+ StartCommand.RaiseCanExecuteChanged();
+ }, x => !TcpServer.IsStarted);
+
+ StopCommand = new RelayCommand(() =>
+ {
+ TcpServer.Stop();
+
+ if (Emulator != null)
+ {
+ Emulator.Stop();
+ }
+ StartCommand.RaiseCanExecuteChanged();
+ StopCommand.RaiseCanExecuteChanged();
+ }, (x) =>
+ {
+ return TcpServer.IsStarted;
+ });
+
+ ConnectCommand = new RelayCommand(() =>
+ {
+ mobileTransporter.Adapter = new TcpSerialAdapter("127.0.0.1", 9999);
+ mobileTransporter.Connect().Subscribe();
+
+ ConnectCommand.RaiseCanExecuteChanged();
+ DisconnectCommand.RaiseCanExecuteChanged();
+
+ }, (x) => !mobileTransporter.IsConnected);
+
+ DisconnectCommand = new RelayCommand(() =>
+ {
+ mobileTransporter.Disconnect().Subscribe();
+
+ ConnectCommand.RaiseCanExecuteChanged();
+ DisconnectCommand.RaiseCanExecuteChanged();
+
+ }, (x) => mobileTransporter.IsConnected);
+
+ InitializeComponent();
+ }
+
+ private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
+ {
+ Emulator = new MachineEmulator(new ProtoTransporter(new TcpSerialAdapter(e.Socket)));
+ Emulator.Start();
+ }
+
+ #endregion
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ var request = MessageFactory.CreateContainer<Stub1Request>();
+ request.Message.A = 5;
+ request.Message.B = 10;
+
+ mobileTransporter.SendRequest<Stub1Request, Stub1Response>(request).Subscribe((response) =>
+ {
+
+ }, (error) =>
+ {
+
+ });
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs b/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs
new file mode 100644
index 000000000..abda393b8
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR;
+using Tango.PMR.Common;
+using Tango.SharedUI;
+
+namespace Tango.Emulator.Models
+{
+ public class StubVM : ExtendedObject
+ {
+ public MessageContainer Message { get; set; }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..7d440978a
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Machine Emulator Utility")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs b/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..3958e81c9
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.Emulator.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.Emulator.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx b/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs b/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..a9e286568
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.Emulator.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings b/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj b/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj
new file mode 100644
index 000000000..0b3cfabb1
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.Emulator</RootNamespace>
+ <AssemblyName>Tango.Emulator</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\Build\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL">
+ <HintPath>..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL">
+ <HintPath>..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Reactive.Core, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net45\System.Reactive.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Linq, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Linq.3.1.1\lib\net45\System.Reactive.Linq.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.PlatformServices, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.PlatformServices.3.1.1\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="MainWindow.xaml.cs">
+ <DependentUpon>MainWindow.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Models\StubVM.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>
+ </SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Integration\Tango.Integration.csproj">
+ <Project>{b6182925-8864-401f-a390-6eff737c4fc7}</Project>
+ <Name>Tango.Integration</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Protobuf\Tango.Protobuf.csproj">
+ <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project>
+ <Name>Tango.Protobuf</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\machine-trans.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\phone.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Emulator/packages.config b/Software/Visual Studio/Tango.Emulator/packages.config
new file mode 100644
index 000000000..72d96268c
--- /dev/null
+++ b/Software/Visual Studio/Tango.Emulator/packages.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net45" />
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+ <package id="MahApps.Metro" version="1.5.0" targetFramework="net45" />
+ <package id="System.Reactive" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Core" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs b/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs
new file mode 100644
index 000000000..0da75704c
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive;
+using System.Reactive.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.Adapters
+{
+ public interface ISerialAdapter : IDisposable
+ {
+ IObservable<Unit> Open();
+ IObservable<Unit> Close();
+ void Write(byte[] data);
+ IObservable<byte[]> ReceiveData();
+ bool IsOpened { get; }
+ IObservable<Unit> SubscribeForDisconnection();
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs b/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs
new file mode 100644
index 000000000..92d0894e1
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Reactive;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Integration.Adapters
+{
+ public class TcpSerialAdapter : ISerialAdapter
+ {
+ private TcpClient _socket;
+ private Thread _receiveThread;
+ private Subject<byte[]> _receiveSubject;
+ private Subject<Unit> _disconnectionSubject;
+
+ public bool IsOpened { get; private set; }
+
+ public String Address { get; set; }
+
+ public int Port { get; set; }
+
+ public TcpSerialAdapter()
+ {
+ _receiveSubject = new Subject<byte[]>();
+ _disconnectionSubject = new Subject<Unit>();
+ }
+
+ public TcpSerialAdapter(String address, int port) : this()
+ {
+ Address = address;
+ Port = port;
+ }
+
+ public TcpSerialAdapter(TcpClient socket) : this()
+ {
+ _socket = socket;
+ Start();
+ }
+
+ public IObservable<Unit> Open()
+ {
+ return Observable.Create<Unit>((x) =>
+ {
+ try
+ {
+ if (!IsOpened)
+ {
+ _socket = new TcpClient(Address, Port);
+ Start();
+ LogManager.Log("Adapter connected.");
+ }
+
+ x.OnNext(Unit.Default);
+ }
+ catch (Exception ex)
+ {
+ x.OnError(LogManager.Log(ex, "Could not connect the adapter."));
+ }
+ finally
+ {
+ x.OnCompleted();
+ }
+
+ return Disposable.Empty;
+
+ }).ObserveOn(Scheduler.Default);
+ }
+
+ private void Start()
+ {
+ IsOpened = true;
+ _receiveThread = new Thread(ReceiveThreadMethod);
+ _receiveThread.IsBackground = true;
+ _receiveThread.Start();
+ }
+
+ public IObservable<Unit> Close()
+ {
+ return Observable.Create<Unit>((x) =>
+ {
+ try
+ {
+ if (IsOpened)
+ {
+ IsOpened = false;
+ _socket.GetStream().Close();
+ _socket.Close();
+ LogManager.Log("Adapter disconnected.");
+ }
+
+ x.OnNext(Unit.Default);
+ }
+ catch (Exception ex)
+ {
+ x.OnError(LogManager.Log(ex, "Could not disconnect the adapter."));
+ }
+ finally
+ {
+ x.OnCompleted();
+ }
+
+ return Disposable.Empty;
+
+ }).ObserveOn(Scheduler.Default);
+ }
+
+ public void Write(byte[] data)
+ {
+ _socket.GetStream().Write(data, 0, data.Length);
+ }
+
+ public IObservable<byte[]> ReceiveData()
+ {
+ return _receiveSubject;
+ }
+
+ private void ReceiveThreadMethod()
+ {
+ int counter = 0;
+
+ try
+ {
+ while (IsOpened)
+ {
+ if (_socket.Available > 0)
+ {
+ byte[] data = new byte[_socket.Available];
+ _socket.GetStream().Read(data, 0, data.Length);
+
+ if (_receiveSubject != null)
+ {
+ _receiveSubject.OnNext(data);
+ }
+ }
+
+ Thread.Sleep(10);
+ counter++;
+
+ if (counter >= 200)
+ {
+ try
+ {
+ if (_socket.Client.Poll(1, SelectMode.SelectRead) && _socket.Client.Available == 0)
+ {
+ Close().Subscribe();
+ _disconnectionSubject.OnError(LogManager.Log(new Exception("Client disconnected.")));
+ return;
+ }
+ }
+ catch (SocketException ex)
+ {
+ Close().Subscribe();
+ _disconnectionSubject.OnError(LogManager.Log(ex));
+ return;
+ }
+
+ counter = 0;
+ }
+ }
+
+ _receiveSubject.OnCompleted();
+ }
+ catch (Exception ex)
+ {
+ _receiveSubject.OnError(LogManager.Log(ex));
+ }
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ public IObservable<Unit> SubscribeForDisconnection()
+ {
+ return _disconnectionSubject;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs b/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs
new file mode 100644
index 000000000..cbb5f00f9
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs
@@ -0,0 +1,131 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Integration.Adapters;
+using Tango.Integration.TCP;
+using Tango.Integration.Transport;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Common;
+using Tango.PMR.Stubs;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+
+namespace Tango.Integration.Emulators
+{
+ public class MachineEmulator : ExtendedObject
+ {
+ private ITransporter _transporter;
+
+ #region Properties
+
+ private bool _isStarted;
+ /// <summary>
+ /// Gets or sets a value indicating whether the emulator is started.
+ /// </summary>
+ public bool IsStarted
+ {
+ get { return _isStarted; }
+ set { _isStarted = value; RaisePropertyChanged(nameof(IsStarted)); InvalidateRelayCommands(); }
+ }
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the start command.
+ /// </summary>
+ public RelayCommand StartCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop command.
+ /// </summary>
+ public RelayCommand StopCommand { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineEmulator"/> class.
+ /// </summary>
+ public MachineEmulator(ITransporter transporter)
+ {
+ _transporter = transporter;
+ _transporter.SubscribeForRequests().Subscribe(HandleRequest);
+ _transporter.SubscribeForDisconnection().Subscribe((x) => {}, (ex) =>
+ {
+ LogManager.Log("Transporter disconnected.");
+ });
+ StartCommand = new RelayCommand(Start, (x) => !IsStarted);
+ StopCommand = new RelayCommand(Stop, (x) => IsStarted);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Stops this instance.
+ /// </summary>
+ public void Stop()
+ {
+ if (IsStarted)
+ {
+ _transporter.Disconnect().Subscribe(x =>
+ {
+ IsStarted = false;
+ }, ex => { throw ex; });
+ }
+ }
+
+ /// <summary>
+ /// Starts this instance.
+ /// </summary>
+ public void Start()
+ {
+ if (!IsStarted)
+ {
+ _transporter.Connect().Subscribe(x =>
+ {
+ IsStarted = true;
+ }, ex => { throw ex; });
+ }
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Handles the request.
+ /// </summary>
+ /// <param name="container">The container.</param>
+ protected void HandleRequest(MessageContainer container)
+ {
+ switch (container.Type)
+ {
+ case MessageType.Stub1Request:
+ Task.Factory.StartNew(() =>
+ {
+ Thread.Sleep(5000);
+
+ var request = MessageFactory.ParseContainer<Stub1Request>(container);
+ var response = MessageFactory.CreateContainer<Stub1Response>(container.Token);
+ response.Message.Sum = request.A + request.B;
+ response.Container.Token = container.Token;
+ _transporter.SendResponse(response);
+ });
+ break;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..d76cafb27
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Machine Integration Layer")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs b/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs
new file mode 100644
index 000000000..21e311b19
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.TCP
+{
+ public class ClientConnectedEventArgs : EventArgs
+ {
+ public TcpClient Socket { get; set; }
+
+ public ClientConnectedEventArgs(TcpClient socket)
+ {
+ Socket = socket;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs b/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs
new file mode 100644
index 000000000..6f24646ae
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Integration.TCP
+{
+ public class TcpServer
+ {
+ private TaskScheduler scheduler;
+
+ /// <summary>
+ /// The TcpListener that is encapsulated behind this Server instance.
+ /// </summary>
+ public TcpListener Listener { get; set; }
+ /// <summary>
+ /// The Port that is used to listen to incoming connections.
+ /// </summary>
+ public int Port { get; set; }
+ /// <summary>
+ /// Returns true if the Server instance is running.
+ /// </summary>
+ public bool IsStarted { get; private set; }
+
+ #region Events
+
+ public event EventHandler<ClientConnectedEventArgs> ClientConnected;
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new Server instance.
+ /// </summary>
+ /// <param name="port">The port number that is used to listen for incoming connections.</param>
+ public TcpServer(int port)
+ {
+ Port = port;
+ scheduler = TaskScheduler.FromCurrentSynchronizationContext();
+ }
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Start Listening for incoming connections.
+ /// </summary>
+ public void Start()
+ {
+ if (!IsStarted)
+ {
+ Listener = new TcpListener(System.Net.IPAddress.Any, Port);
+ Listener.Start();
+ IsStarted = true;
+ LogManager.Log("Server Started!");
+ WaitForConnection();
+ }
+ }
+ /// <summary>
+ /// Stop listening for incoming connections.
+ /// </summary>
+ public void Stop()
+ {
+ if (IsStarted)
+ {
+ Listener.Stop();
+ IsStarted = false;
+ LogManager.Log("Server Stopped!");
+ }
+ }
+
+ #endregion
+
+ #region Incoming Connections Methods
+
+ private void WaitForConnection()
+ {
+ Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null);
+ }
+
+ private void ConnectionHandler(IAsyncResult ar)
+ {
+ if (IsStarted)
+ {
+ try
+ {
+ OnClientConnected(Listener.EndAcceptTcpClient(ar));
+ Debug.WriteLine("New Client Connected");
+ WaitForConnection();
+ }
+ catch (ObjectDisposedException ex)
+ {
+ //Ignore..
+ }
+ }
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ protected virtual void OnClientConnected(TcpClient socket)
+ {
+ LogManager.Log("Client Connected.");
+
+ Task.Factory.StartNew(() =>
+ {
+
+ ClientConnected?.Invoke(this, new ClientConnectedEventArgs(socket));
+
+ },CancellationToken.None,TaskCreationOptions.None,scheduler);
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj
new file mode 100644
index 000000000..da3ee255e
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B6182925-8864-401F-A390-6EFF737C4FC7}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Integration</RootNamespace>
+ <AssemblyName>Tango.Integration</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\Build\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Reactive.Core, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net45\System.Reactive.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Linq, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Linq.3.1.1\lib\net45\System.Reactive.Linq.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.PlatformServices, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.PlatformServices.3.1.1\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ <Reference Include="WindowsBase" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="Adapters\ISerialAdapter.cs" />
+ <Compile Include="Adapters\TcpSerialAdapter.cs" />
+ <Compile Include="Emulators\MachineEmulator.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="TCP\ClientConnectedEventArgs.cs" />
+ <Compile Include="TCP\TcpServer.cs" />
+ <Compile Include="Transport\ITransporter.cs" />
+ <Compile Include="Transport\MessageBase.cs" />
+ <Compile Include="Transport\ProtoTransporter.cs" />
+ <Compile Include="Transport\RequestMessage.cs" />
+ <Compile Include="Transport\ResponseMessage.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Protobuf\Tango.Protobuf.csproj">
+ <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project>
+ <Name>Tango.Protobuf</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs b/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs
new file mode 100644
index 000000000..cb4693efa
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs
@@ -0,0 +1,66 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive;
+using System.Reactive.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Integration.Adapters;
+using Tango.PMR;
+using Tango.PMR.Common;
+
+namespace Tango.Integration.Transport
+{
+ public interface ITransporter : IDisposable
+ {
+ /// <summary>
+ /// Gets the serial adapter.
+ /// </summary>
+ ISerialAdapter Adapter { get; set; }
+
+ /// <summary>
+ /// Gets a value indicating whether this transporter is connected.
+ /// </summary>
+ bool IsConnected { get; }
+
+ /// <summary>
+ /// Sends a request.
+ /// </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>
+ /// <returns></returns>
+ IObservable<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a response.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <returns></returns>
+ IObservable<object> SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Subscribes for requests.
+ /// </summary>
+ /// <returns></returns>
+ IObservable<MessageContainer> SubscribeForRequests();
+
+ /// <summary>
+ /// Opens a connection on the <see cref="Adapter"/>.
+ /// </summary>
+ IObservable<Unit> Connect();
+
+ /// <summary>
+ /// Closes the connection on the <see cref="Adapter"/>.
+ /// </summary>
+ IObservable<Unit> Disconnect();
+
+ /// <summary>
+ /// Subscribes for disconnection.
+ /// </summary>
+ /// <returns></returns>
+ IObservable<Unit> SubscribeForDisconnection();
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs b/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs
new file mode 100644
index 000000000..46d5b3109
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Subjects;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.Transport
+{
+ internal class MessageBase
+ {
+ public String Token { get; set; }
+
+ public Subject<object> Subject { get; set; }
+
+ private Func<byte[]> _toBytes;
+
+ public object Message { get; set; }
+
+ public byte[] ToBytes()
+ {
+ return _toBytes();
+ }
+
+ public MessageBase(String token, Subject<object> subject, object message, Func<byte[]> toBytes)
+ {
+ Token = token;
+ Subject = subject;
+ Message = message;
+ _toBytes = toBytes;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs b/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs
new file mode 100644
index 000000000..aaaa5a5ce
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs
@@ -0,0 +1,255 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Tango.Integration.Adapters;
+using Tango.PMR;
+using Tango.PMR.Common;
+using System.Collections.Concurrent;
+using System.Reactive.Subjects;
+using System.Threading;
+using System.Reactive;
+using System.Reactive.Disposables;
+using Tango.Logging;
+
+namespace Tango.Integration.Transport
+{
+ public class ProtoTransporter : ITransporter
+ {
+ private ConcurrentQueue<MessageBase> _sendingQueue;
+ private List<RequestMessage> _pendingRequests;
+ private ConcurrentQueue<byte[]> _arrivedResponses;
+
+ private Subject<MessageContainer> _requestSubject;
+
+ private Thread _pushThread;
+ private Thread _pullThread;
+
+ private ISerialAdapter _adapter;
+ /// <summary>
+ /// Gets the serial adapter.
+ /// </summary>
+ public ISerialAdapter Adapter
+ {
+ get { return _adapter; }
+ set
+ {
+ _adapter = value;
+
+ if (IsConnected)
+ {
+ Connect();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this transporter is connected.
+ /// </summary>
+ public bool IsConnected { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtoTransporter"/> class.
+ /// </summary>
+ public ProtoTransporter()
+ {
+ _sendingQueue = new ConcurrentQueue<MessageBase>();
+ _pendingRequests = new List<RequestMessage>();
+ _arrivedResponses = new ConcurrentQueue<byte[]>();
+ _requestSubject = new Subject<MessageContainer>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtoTransporter"/> class.
+ /// </summary>
+ /// <param name="adapter">The adapter.</param>
+ public ProtoTransporter(ISerialAdapter adapter) : this()
+ {
+ Adapter = adapter;
+ }
+
+ /// <summary>
+ /// Opens a connection on the <see cref="Adapter" />.
+ /// </summary>
+ public IObservable<Unit> Connect()
+ {
+ IsConnected = true;
+ Adapter.ReceiveData().Subscribe((data) => { _arrivedResponses.Enqueue(data); });
+ StartThreads();
+ return Adapter.Open();
+ }
+
+ /// <summary>
+ /// Closes the connection on the <see cref="Adapter" />.
+ /// </summary>
+ public IObservable<Unit> Disconnect()
+ {
+ IsConnected = false;
+ return Adapter.Close();
+ }
+
+ /// <summary>
+ /// Starts the threads.
+ /// </summary>
+ private void StartThreads()
+ {
+ _pullThread = new Thread(PullThreadMethod);
+ _pullThread.IsBackground = true;
+ _pullThread.Start();
+
+ _pushThread = new Thread(PushThreadMethod);
+ _pushThread.IsBackground = true;
+ _pushThread.Start();
+ }
+
+ /// <summary>
+ /// Push thread loop.
+ /// </summary>
+ private void PushThreadMethod()
+ {
+ while (IsConnected)
+ {
+ if (_sendingQueue.Count > 0)
+ {
+ MessageBase message;
+ if (_sendingQueue.TryDequeue(out message))
+ {
+ try
+ {
+ Adapter.Write(message.ToBytes());
+
+ if (message.GetType() == typeof(RequestMessage))
+ {
+ _pendingRequests.Add(message as RequestMessage);
+ }
+ else
+ {
+ message.Subject.OnNext(new object());
+ message.Subject.OnCompleted();
+ }
+ }
+ catch (Exception ex)
+ {
+ message.Subject.OnError(ex);
+ }
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+ }
+
+ /// <summary>
+ /// Pull thread loop.
+ /// </summary>
+ private void PullThreadMethod()
+ {
+ while (IsConnected)
+ {
+ byte[] data;
+
+ if (_arrivedResponses.Count > 0)
+ {
+ if (_arrivedResponses.TryDequeue(out data))
+ {
+ MessageContainer container = MessageFactory.ParseContainerPartial(data);
+ RequestMessage request = _pendingRequests.SingleOrDefault(x => x.Token == container.Token);
+
+ if (request != null)
+ {
+ _pendingRequests.Remove(request);
+
+ try
+ {
+ request.Subject.OnNext(MessageFactory.ParseContainer(container));
+ }
+ catch (Exception ex)
+ {
+ request.Subject.OnError(ex);
+ }
+ }
+ else
+ {
+ try
+ {
+ _requestSubject.OnNext(container);
+ }
+ catch (Exception ex)
+ {
+ _requestSubject.OnError(ex);
+ }
+ }
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Disconnect();
+ }
+
+ /// <summary>
+ /// Sends a request.
+ /// </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>
+ /// <returns></returns>
+ public IObservable<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ Subject<object> subject = new Subject<object>();
+ RequestMessage message = new RequestMessage(request.Container.Token, subject, request, request.ToBytes);
+ _sendingQueue.Enqueue(message);
+ IObservable<Response> observer = subject.Select(x => (Response)x);
+ return observer;
+ }
+
+ /// <summary>
+ /// Sends a response.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <returns></returns>
+ public IObservable<object> SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>
+ {
+ Subject<object> subject = new Subject<object>();
+ ResponseMessage message = new ResponseMessage(Guid.NewGuid().ToString(), subject, response, response.ToBytes);
+ _sendingQueue.Enqueue(message);
+ return subject;
+ }
+
+ /// <summary>
+ /// Subscribes for requests.
+ /// </summary>
+ /// <returns></returns>
+ public IObservable<MessageContainer> SubscribeForRequests()
+ {
+ return _requestSubject;
+ }
+
+ /// <summary>
+ /// Subscribes for disconnection.
+ /// </summary>
+ /// <returns></returns>
+ public IObservable<Unit> SubscribeForDisconnection()
+ {
+ var observable = Adapter.SubscribeForDisconnection();
+ observable.Subscribe((x) => { }, (ex) =>
+ {
+ LogManager.Log("Adapter closed. Disconnecting...");
+ Disconnect().Subscribe();
+ });
+
+ return observable;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs b/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs
new file mode 100644
index 000000000..149712bee
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Subjects;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.Transport
+{
+ internal class RequestMessage : MessageBase
+ {
+ public RequestMessage(String token, Subject<object> subject, object message, Func<byte[]> toBytes) : base(token, subject, message, toBytes)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs b/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs
new file mode 100644
index 000000000..8eb956eec
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Subjects;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.Transport
+{
+ internal class ResponseMessage : MessageBase
+ {
+ internal ResponseMessage(String token, Subject<object> subject, object message, Func<byte[]> toBytes) : base(token, subject, message, toBytes)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Integration/packages.config b/Software/Visual Studio/Tango.Integration/packages.config
new file mode 100644
index 000000000..5a7de5f4e
--- /dev/null
+++ b/Software/Visual Studio/Tango.Integration/packages.config
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+ <package id="System.Reactive" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Core" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net45" />
+ <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs
index 9155db1b4..161c5a04e 100644
--- a/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Logging Library")]
+[assembly: AssemblyTitle("Tango - Logging Library")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs b/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs
index c887da2f4..4b4a437a9 100644
--- a/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs
+++ b/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs
@@ -23,13 +23,14 @@ namespace Tango.PMR.Common {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChZNZXNzYWdlQ29udGFpbmVyLnByb3RvEhBUYW5nby5QTVIuQ29tbW9uGhFN",
- "ZXNzYWdlVHlwZS5wcm90byJNChBNZXNzYWdlQ29udGFpbmVyEisKBFR5cGUY",
- "ASABKA4yHS5UYW5nby5QTVIuQ29tbW9uLk1lc3NhZ2VUeXBlEgwKBERhdGEY",
- "AiABKAxiBnByb3RvMw=="));
+ "ZXNzYWdlVHlwZS5wcm90byJcChBNZXNzYWdlQ29udGFpbmVyEisKBFR5cGUY",
+ "ASABKA4yHS5UYW5nby5QTVIuQ29tbW9uLk1lc3NhZ2VUeXBlEg0KBVRva2Vu",
+ "GAIgASgJEgwKBERhdGEYAyABKAxCHAoaY29tLnR3aW5lLnRhbmdvLnBtci5j",
+ "b21tb25iBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.Common.MessageTypeReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.MessageContainer), global::Tango.PMR.Common.MessageContainer.Parser, new[]{ "Type", "Data" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.MessageContainer), global::Tango.PMR.Common.MessageContainer.Parser, new[]{ "Type", "Token", "Data" }, null, null, null)
}));
}
#endregion
@@ -61,6 +62,7 @@ namespace Tango.PMR.Common {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainer(MessageContainer other) : this() {
type_ = other.type_;
+ token_ = other.token_;
data_ = other.data_;
}
@@ -80,8 +82,19 @@ namespace Tango.PMR.Common {
}
}
+ /// <summary>Field number for the "Token" field.</summary>
+ public const int TokenFieldNumber = 2;
+ private string token_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Token {
+ get { return token_; }
+ set {
+ token_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
/// <summary>Field number for the "Data" field.</summary>
- public const int DataFieldNumber = 2;
+ public const int DataFieldNumber = 3;
private pb::ByteString data_ = pb::ByteString.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Data {
@@ -105,6 +118,7 @@ namespace Tango.PMR.Common {
return true;
}
if (Type != other.Type) return false;
+ if (Token != other.Token) return false;
if (Data != other.Data) return false;
return true;
}
@@ -113,6 +127,7 @@ namespace Tango.PMR.Common {
public override int GetHashCode() {
int hash = 1;
if (Type != 0) hash ^= Type.GetHashCode();
+ if (Token.Length != 0) hash ^= Token.GetHashCode();
if (Data.Length != 0) hash ^= Data.GetHashCode();
return hash;
}
@@ -128,8 +143,12 @@ namespace Tango.PMR.Common {
output.WriteRawTag(8);
output.WriteEnum((int) Type);
}
- if (Data.Length != 0) {
+ if (Token.Length != 0) {
output.WriteRawTag(18);
+ output.WriteString(Token);
+ }
+ if (Data.Length != 0) {
+ output.WriteRawTag(26);
output.WriteBytes(Data);
}
}
@@ -140,6 +159,9 @@ namespace Tango.PMR.Common {
if (Type != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
}
+ if (Token.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Token);
+ }
if (Data.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
}
@@ -154,6 +176,9 @@ namespace Tango.PMR.Common {
if (other.Type != 0) {
Type = other.Type;
}
+ if (other.Token.Length != 0) {
+ Token = other.Token;
+ }
if (other.Data.Length != 0) {
Data = other.Data;
}
@@ -172,6 +197,10 @@ namespace Tango.PMR.Common {
break;
}
case 18: {
+ Token = input.ReadString();
+ break;
+ }
+ case 26: {
Data = input.ReadBytes();
break;
}
diff --git a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
index 667453399..c2ca7a47d 100644
--- a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
+++ b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
@@ -22,9 +22,10 @@ namespace Tango.PMR.Common {
static MessageTypeReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiosCgtNZXNz",
- "YWdlVHlwZRIHCgNSR0IQABIHCgNKb2IQARILCgdTZWdtZW50EAJiBnByb3Rv",
- "Mw=="));
+ "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbipRCgtNZXNz",
+ "YWdlVHlwZRIHCgNSR0IQABIHCgNKb2IQARILCgdTZWdtZW50EAISEAoMU3R1",
+ "YjFSZXF1ZXN0EAMSEQoNU3R1YjFSZXNwb25zZRAEQhwKGmNvbS50d2luZS50",
+ "YW5nby5wbXIuY29tbW9uYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null));
@@ -37,6 +38,8 @@ namespace Tango.PMR.Common {
[pbr::OriginalName("RGB")] Rgb = 0,
[pbr::OriginalName("Job")] Job = 1,
[pbr::OriginalName("Segment")] Segment = 2,
+ [pbr::OriginalName("Stub1Request")] Stub1Request = 3,
+ [pbr::OriginalName("Stub1Response")] Stub1Response = 4,
}
#endregion
diff --git a/Software/Visual Studio/Tango.PMR/Common/RGB.cs b/Software/Visual Studio/Tango.PMR/Common/RGB.cs
index 3e69cf66c..23f335254 100644
--- a/Software/Visual Studio/Tango.PMR/Common/RGB.cs
+++ b/Software/Visual Studio/Tango.PMR/Common/RGB.cs
@@ -23,7 +23,8 @@ namespace Tango.PMR.Common {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CglSR0IucHJvdG8SEFRhbmdvLlBNUi5Db21tb24iJgoDUkdCEgkKAVIYASAB",
- "KAUSCQoBRxgCIAEoBRIJCgFCGAMgASgFYgZwcm90bzM="));
+ "KAUSCQoBRxgCIAEoBRIJCgFCGAMgASgFQhwKGmNvbS50d2luZS50YW5nby5w",
+ "bXIuY29tbW9uYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/Software/Visual Studio/Tango.PMR/Jobs/Job.cs b/Software/Visual Studio/Tango.PMR/Jobs/Job.cs
index 543bc1e43..d505436d4 100644
--- a/Software/Visual Studio/Tango.PMR/Jobs/Job.cs
+++ b/Software/Visual Studio/Tango.PMR/Jobs/Job.cs
@@ -24,7 +24,8 @@ namespace Tango.PMR.Jobs {
string.Concat(
"CglKb2IucHJvdG8SDlRhbmdvLlBNUi5Kb2JzGg1TZWdtZW50LnByb3RvIj4K",
"A0pvYhIMCgROYW1lGAEgASgJEikKCFNlZ21lbnRzGAIgAygLMhcuVGFuZ28u",
- "UE1SLkpvYnMuU2VnbWVudGIGcHJvdG8z"));
+ "UE1SLkpvYnMuU2VnbWVudEIaChhjb20udHdpbmUudGFuZ28ucG1yLmpvYnNi",
+ "BnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.Jobs.SegmentReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs b/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs
index 2b2aa04de..440650812 100644
--- a/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs
+++ b/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs
@@ -24,7 +24,8 @@ namespace Tango.PMR.Jobs {
string.Concat(
"Cg1TZWdtZW50LnByb3RvEg5UYW5nby5QTVIuSm9icxoJUkdCLnByb3RvIk0K",
"B1NlZ21lbnQSDAoETmFtZRgBIAEoCRIOCgZMZW5ndGgYAiABKAUSJAoFQ29s",
- "b3IYAyABKAsyFS5UYW5nby5QTVIuQ29tbW9uLlJHQmIGcHJvdG8z"));
+ "b3IYAyABKAsyFS5UYW5nby5QTVIuQ29tbW9uLlJHQkIaChhjb20udHdpbmUu",
+ "dGFuZ28ucG1yLmpvYnNiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.Common.RGBReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/Software/Visual Studio/Tango.PMR/MessageFactory.cs b/Software/Visual Studio/Tango.PMR/MessageFactory.cs
index 9dc8643ee..b507b5c4e 100644
--- a/Software/Visual Studio/Tango.PMR/MessageFactory.cs
+++ b/Software/Visual Studio/Tango.PMR/MessageFactory.cs
@@ -25,6 +25,18 @@ namespace Tango.PMR
}
/// <summary>
+ /// Creates a new <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public static TangoMessage<T> CreateContainer<T>(String token) where T : IMessage<T>
+ {
+ TangoMessage<T> message = new TangoMessage<T>(Activator.CreateInstance<T>(), (MessageType)Enum.Parse(typeof(MessageType), typeof(T).Name));
+ message.Container.Token = token;
+ return message;
+ }
+
+ /// <summary>
/// Parses the specified <see cref="MessageContainer"/> bytes to <see cref="TangoMessage{T}"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
@@ -37,5 +49,37 @@ namespace Tango.PMR
TangoMessage<T> tangoMessage = new TangoMessage<T>(parser.ParseFrom(container.Data), container.Type);
return tangoMessage;
}
+
+ /// <summary>
+ /// Parses the specified <see cref="MessageContainer"/> bytes to <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="data">The data.</param>
+ /// <returns></returns>
+ public static T ParseContainer<T>(MessageContainer container) where T : IMessage<T>
+ {
+ MessageParser<T> parser = new MessageParser<T>(() => Activator.CreateInstance<T>());
+ return parser.ParseFrom(container.Data);
+ }
+
+
+ public static IMessage ParseContainer(MessageContainer container)
+ {
+ var type = typeof(MessageFactory).Assembly.GetTypes().ToList().SingleOrDefault(x => x.Name == container.Type.ToString());
+ MessageParser parser = type.GetProperty("Parser").GetValue(container) as MessageParser;
+ return parser.ParseFrom(container.Data);
+ }
+
+ /// <summary>
+ /// Parses the container partial.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="data">The data.</param>
+ /// <returns></returns>
+ public static MessageContainer ParseContainerPartial(byte[] data)
+ {
+ MessageContainer container = MessageContainer.Parser.ParseFrom(data);
+ return container;
+ }
}
}
diff --git a/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs
index e795a8874..03126049b 100644
--- a/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Protobuf Message Repository")]
+[assembly: AssemblyTitle("Tango - Protobuf Message Repository")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs b/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs
new file mode 100644
index 000000000..7d4960e9b
--- /dev/null
+++ b/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs
@@ -0,0 +1,305 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Stub1.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.Stubs {
+
+ /// <summary>Holder for reflection information generated from Stub1.proto</summary>
+ public static partial class Stub1Reflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for Stub1.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static Stub1Reflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CgtTdHViMS5wcm90bxIPVGFuZ28uUE1SLlN0dWJzIiQKDFN0dWIxUmVxdWVz",
+ "dBIJCgFBGAEgASgFEgkKAUIYAiABKAUiHAoNU3R1YjFSZXNwb25zZRILCgNT",
+ "dW0YASABKAVCGwoZY29tLnR3aW5lLnRhbmdvLnBtci5zdHVic2IGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Request), global::Tango.PMR.Stubs.Stub1Request.Parser, new[]{ "A", "B" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Response), global::Tango.PMR.Stubs.Stub1Response.Parser, new[]{ "Sum" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class Stub1Request : pb::IMessage<Stub1Request> {
+ private static readonly pb::MessageParser<Stub1Request> _parser = new pb::MessageParser<Stub1Request>(() => new Stub1Request());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<Stub1Request> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Request() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Request(Stub1Request other) : this() {
+ a_ = other.a_;
+ b_ = other.b_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Request Clone() {
+ return new Stub1Request(this);
+ }
+
+ /// <summary>Field number for the "A" field.</summary>
+ public const int AFieldNumber = 1;
+ private int a_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int A {
+ get { return a_; }
+ set {
+ a_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "B" field.</summary>
+ public const int BFieldNumber = 2;
+ private int b_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int B {
+ get { return b_; }
+ set {
+ b_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as Stub1Request);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(Stub1Request other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (A != other.A) return false;
+ if (B != other.B) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (A != 0) hash ^= A.GetHashCode();
+ if (B != 0) hash ^= B.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 (A != 0) {
+ output.WriteRawTag(8);
+ output.WriteInt32(A);
+ }
+ if (B != 0) {
+ output.WriteRawTag(16);
+ output.WriteInt32(B);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (A != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(A);
+ }
+ if (B != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(B);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(Stub1Request other) {
+ if (other == null) {
+ return;
+ }
+ if (other.A != 0) {
+ A = other.A;
+ }
+ if (other.B != 0) {
+ B = other.B;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ A = input.ReadInt32();
+ break;
+ }
+ case 16: {
+ B = input.ReadInt32();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class Stub1Response : pb::IMessage<Stub1Response> {
+ private static readonly pb::MessageParser<Stub1Response> _parser = new pb::MessageParser<Stub1Response>(() => new Stub1Response());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<Stub1Response> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[1]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Response() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Response(Stub1Response other) : this() {
+ sum_ = other.sum_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Stub1Response Clone() {
+ return new Stub1Response(this);
+ }
+
+ /// <summary>Field number for the "Sum" field.</summary>
+ public const int SumFieldNumber = 1;
+ private int sum_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Sum {
+ get { return sum_; }
+ set {
+ sum_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as Stub1Response);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(Stub1Response other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Sum != other.Sum) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Sum != 0) hash ^= Sum.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 (Sum != 0) {
+ output.WriteRawTag(8);
+ output.WriteInt32(Sum);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Sum != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(Sum);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(Stub1Response other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Sum != 0) {
+ Sum = other.Sum;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ Sum = input.ReadInt32();
+ 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 93f2f41d8..8039b352a 100644
--- a/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj
+++ b/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj
@@ -53,6 +53,7 @@
<Compile Include="Jobs\Segment.cs" />
<Compile Include="MessageFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Stubs\Stub1.cs" />
<Compile Include="TangoMessage.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Software/Visual Studio/Tango.PMR/TangoMessage.cs b/Software/Visual Studio/Tango.PMR/TangoMessage.cs
index 98cfdebe5..71d4a046b 100644
--- a/Software/Visual Studio/Tango.PMR/TangoMessage.cs
+++ b/Software/Visual Studio/Tango.PMR/TangoMessage.cs
@@ -16,6 +16,11 @@ namespace Tango.PMR
public class TangoMessage<T> where T : IMessage<T>
{
/// <summary>
+ /// Gets the container.
+ /// </summary>
+ public MessageContainer Container { get; }
+
+ /// <summary>
/// Gets or sets the message.
/// </summary>
public T Message { get; set; }
@@ -34,6 +39,10 @@ namespace Tango.PMR
{
Message = message;
Type = type;
+
+ Container = new MessageContainer();
+ Container.Token = Guid.NewGuid().ToString();
+ Container.Type = Type;
}
/// <summary>
@@ -42,13 +51,11 @@ namespace Tango.PMR
/// <returns></returns>
public byte[] ToBytes()
{
- MessageContainer container = new MessageContainer();
- container.Type = Type;
- container.Data = Message.ToByteString();
+ Container.Data = Message.ToByteString();
using (MemoryStream ms = new MemoryStream())
{
- container.WriteTo(ms);
+ Container.WriteTo(ms);
return ms.ToArray();
}
}
diff --git a/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs
index 37ad6afb4..2296973b8 100644
--- a/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Protobuf Components")]
+[assembly: AssemblyTitle("Tango - Protobuf Components")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs
index ee384bb30..f30c525cc 100644
--- a/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Shared UI Components")]
+[assembly: AssemblyTitle("Tango - Shared UI Components")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs
index d4438885e..0551f8f77 100644
--- a/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Unit Testing")]
+[assembly: AssemblyTitle("Tango - Unit Testing")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.sln b/Software/Visual Studio/Tango.sln
index 3013eef96..e1d820bea 100644
--- a/Software/Visual Studio/Tango.sln
+++ b/Software/Visual Studio/Tango.sln
@@ -31,6 +31,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.PMR", "Tango.PMR\Tango.PMR.csproj", "{E4927038-348D-4295-AAF4-861C58CB3943}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Emulator", "Tango.Emulator\Tango.Emulator.csproj", "{FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Integration", "Tango.Integration\Tango.Integration.csproj", "{B6182925-8864-401F-A390-6EFF737C4FC7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -69,6 +73,14 @@ Global
{E4927038-348D-4295-AAF4-861C58CB3943}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4927038-348D-4295-AAF4-861C58CB3943}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4927038-348D-4295-AAF4-861C58CB3943}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6182925-8864-401F-A390-6EFF737C4FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6182925-8864-401F-A390-6EFF737C4FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6182925-8864-401F-A390-6EFF737C4FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6182925-8864-401F-A390-6EFF737C4FC7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs
index 7232a9b6d..76b91d4da 100644
--- a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs
+++ b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs
@@ -47,12 +47,12 @@ namespace Tango.Protobuf.CLI
}
}
- return ExitSuccess("Folder compiled to " + Path.GetFullPath(options.SourceFolder));
+ return ExitSuccess("Protobuf folder compiled to " + Path.GetFullPath(options.SourceFolder));
}
private static int ExitSuccess(String text)
{
- Console.WriteLine("Done!");
+ Console.WriteLine(text);
return 0;
}
diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs
index 00ace1d5d..316919706 100644
--- a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Protobuf Compilation CLI")]
+[assembly: AssemblyTitle("Tango - Protobuf Compilation CLI")]
[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs
index 002635e32..f391aa2a5 100644
--- a/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs
+++ b/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: AssemblyTitle("Twine - Protobuf Compilation Utility")]
+[assembly: AssemblyTitle("Tango - Protobuf Compilation Utility")]
[assembly: ComVisible(false)] \ No newline at end of file