aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy <roy.mail.net@gmail.com>2017-11-23 00:37:30 +0200
committerRoy <roy.mail.net@gmail.com>2017-11-23 00:37:30 +0200
commit14374562c002481b102feb8e25c7036cafb59853 (patch)
treedf39d0dc72981af63544e0c84eefc8146e3a371a /Software
parent62ceb1153be41b798c65c195df11ac329bb9315c (diff)
downloadTango-14374562c002481b102feb8e25c7036cafb59853.tar.gz
Tango-14374562c002481b102feb8e25c7036cafb59853.zip
Fixed issue with TcpServer Synchronization Context initialization.
Completed Tango Transport Router Utility.
Diffstat (limited to 'Software')
-rw-r--r--Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/MainWindow.xaml2
-rw-r--r--Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Tango.TransportRouter.UI.csproj2
-rw-r--r--Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/ViewModels/MainViewVM.cs178
-rw-r--r--Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Views/MainView.xaml160
5 files changed, 326 insertions, 22 deletions
diff --git a/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs
index 8ce79757a..36e0869f3 100644
--- a/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs
+++ b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs
@@ -45,7 +45,6 @@ namespace Tango.Transport.Servers
public TcpServer(int port)
{
Port = port;
- scheduler = TaskScheduler.FromCurrentSynchronizationContext();
}
#endregion
@@ -58,6 +57,11 @@ namespace Tango.Transport.Servers
{
if (!IsStarted)
{
+ if (scheduler == null)
+ {
+ scheduler = TaskScheduler.FromCurrentSynchronizationContext();
+ }
+
Listener = new TcpListener(System.Net.IPAddress.Any, Port);
Listener.Start();
IsStarted = true;
diff --git a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/MainWindow.xaml
index e94d1657a..001a7f01d 100644
--- a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/MainWindow.xaml
@@ -9,7 +9,7 @@
xmlns:views="clr-namespace:Tango.TransportRouter.UI.Views"
xmlns:local="clr-namespace:Tango.TransportRouter.UI"
mc:Ignorable="d"
- Title="Tango Transport Router" Height="200" Width="545" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}">
+ Title="Tango Transport Router" Height="220" Width="545" ResizeMode="CanMinimize" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid Margin="10">
<views:MainView DataContext="{StaticResource MainViewVM}"></views:MainView>
</Grid>
diff --git a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Tango.TransportRouter.UI.csproj b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Tango.TransportRouter.UI.csproj
index eb749873a..d05260a72 100644
--- a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Tango.TransportRouter.UI.csproj
+++ b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Tango.TransportRouter.UI.csproj
@@ -18,7 +18,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
- <OutputPath>..\Build\Debug\</OutputPath>
+ <OutputPath>..\..\Build\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
diff --git a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/ViewModels/MainViewVM.cs
index 87498c55c..a98f2fa7b 100644
--- a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/ViewModels/MainViewVM.cs
@@ -2,9 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Threading;
using Tango.SharedUI;
using Tango.SharedUI.Commands;
+using Tango.Transport.Adapters;
using Tango.Transport.Routing;
using Tango.Transport.Servers;
@@ -12,37 +16,187 @@ namespace Tango.TransportRouter.UI.ViewModels
{
public class MainViewVM : ExtendedObject
{
- private SimpleTransportRouter _router;
+ private TransportRoutingChannel _channel;
private TcpServer _server;
+ private UsbTransportAdapter _usbAdapter;
+ private TcpTransportAdapter _tcpAdapter;
- public RelayCommand StartCommand { get; set; }
+ #region Properties
- public RelayCommand StopCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the usb ports.
+ /// </summary>
+ public List<String> UsbPorts { get; set; }
+
+ private String _selectedUsbPort;
+ /// <summary>
+ /// Gets or sets the selected USB port.
+ /// </summary>
+ public String SelectedUsbPort
+ {
+ get { return _selectedUsbPort; }
+ set { _selectedUsbPort = value; RaisePropertyChanged(nameof(SelectedUsbPort)); }
+ }
+
+ private bool _isStarted;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is started.
+ /// </summary>
+ public bool IsStarted
+ {
+ get { return _isStarted; }
+ set { _isStarted = value; RaisePropertyChanged(nameof(IsStarted)); }
+ }
+
+ private bool _isWaitingForTCP;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is waiting for TCP.
+ /// </summary>
+ public bool IsWaitingForTCP
+ {
+ get { return _isWaitingForTCP; }
+ set { _isWaitingForTCP = value; RaisePropertyChanged(nameof(IsWaitingForTCP)); }
+ }
+
+ private bool _tcpOn;
+
+ public bool TcpOn
+ {
+ get { return _tcpOn; }
+ set { _tcpOn = value; RaisePropertyChanged(nameof(TcpOn)); }
+ }
+
+ private bool _usbOn;
+
+ public bool UsbOn
+ {
+ get { return _usbOn; }
+ set { _usbOn = value; RaisePropertyChanged(nameof(UsbOn)); }
+ }
+
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the toggle start stop command.
+ /// </summary>
+ public RelayCommand ToggleStartStopCommand { get; set; }
+
+ #endregion
public MainViewVM()
{
_server = new TcpServer(9999);
- _router = new SimpleTransportRouter();
- StartCommand = new RelayCommand(Start);
- StopCommand = new RelayCommand(Stop);
+ ToggleStartStopCommand = new RelayCommand(ToggleStartStop);
_server.ClientConnected += _server_ClientConnected;
+
+ UsbPorts = Enumerable.Range(1, 9).Select(x => "COM" + x).ToList();
+ SelectedUsbPort = UsbPorts.First();
+
+
+ }
+
+ private void ToggleStartStop()
+ {
+ if (IsStarted)
+ {
+ Stop();
+ }
+ else
+ {
+ Start();
+ }
+ }
+
+ private async void Stop()
+ {
+ try
+ {
+ _server.Stop();
+
+ if (_tcpAdapter != null)
+ {
+ await _tcpAdapter.Disconnect();
+ }
+
+ await _usbAdapter.Disconnect();
+ IsStarted = false;
+ IsWaitingForTCP = false;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ private async void Start()
+ {
+ try
+ {
+ _usbAdapter = new UsbTransportAdapter(SelectedUsbPort);
+ _server.Start();
+ await _usbAdapter.Connect();
+ IsStarted = true;
+ IsWaitingForTCP = true;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ private async void _server_ClientConnected(object sender, ClientConnectedEventArgs e)
+ {
+ IsWaitingForTCP = false;
+
+ _tcpAdapter = new TcpTransportAdapter(e.Socket);
+ await _tcpAdapter.Connect();
+
+ _channel = new TransportRoutingChannel(_usbAdapter, _tcpAdapter);
+
+ _usbAdapter.DataAvailable -= _usbAdapter_DataAvailable;
+ _tcpAdapter.DataAvailable -= _tcpAdapter_DataAvailable;
+ _usbAdapter.DataAvailable += _usbAdapter_DataAvailable;
+ _tcpAdapter.DataAvailable += _tcpAdapter_DataAvailable;
}
- private void Stop(object obj)
+ private void _tcpAdapter_DataAvailable(object sender, byte[] e)
{
- throw new NotImplementedException();
+ InvokeUI(() =>
+ {
+ TcpOn = true;
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromMilliseconds(100);
+ timer.Tick += (x, y) =>
+ {
+ TcpOn = false; timer.Stop();
+ };
+ timer.Start();
+ });
}
- private void Start(object obj)
+ private void _usbAdapter_DataAvailable(object sender, byte[] e)
{
- throw new NotImplementedException();
+ InvokeUI(() =>
+ {
+ UsbOn = true;
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromMilliseconds(100);
+ timer.Tick += (x, y) =>
+ {
+ UsbOn = false; timer.Stop();
+ };
+ timer.Start();
+ });
}
- private void _server_ClientConnected(object sender, ClientConnectedEventArgs e)
+ private void InvokeUI(Action action)
{
- throw new NotImplementedException();
+ Application.Current.Dispatcher.BeginInvoke(action);
}
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Views/MainView.xaml b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Views/MainView.xaml
index 2d0b9d57a..07a4a963e 100644
--- a/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/Utilities/Tango.TransportRouter.UI/Views/MainView.xaml
@@ -2,11 +2,20 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:Tango.TransportRouter.UI.Views"
mc:Ignorable="d"
- d:DesignHeight="200" d:DesignWidth="545" Background="#202020">
+ d:DesignHeight="170" d:DesignWidth="545" Background="#202020">
+
+ <UserControl.Resources>
+ <SolidColorBrush Color="#42C300" x:Key="on"></SolidColorBrush>
+ <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"></converters:BooleanToVisibilityInverseConverter>
+ <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></converters:BooleanToVisibilityConverter>
+ </UserControl.Resources>
+
<Grid>
<Grid>
<Grid.RowDefinitions>
@@ -47,16 +56,85 @@
<ColumnDefinition/>
</Grid.ColumnDefinitions>
- <Ellipse Grid.Column="0" Width="16" Height="16" Fill="Black"></Ellipse>
- <Ellipse Grid.Column="1" Width="16" Height="16" Fill="Black"></Ellipse>
+ <Ellipse Grid.Column="0" Width="16" Height="16">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="Black"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.15" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding UsbOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.0" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <Ellipse Grid.Column="1" Width="16" Height="16">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="Black"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.10" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding UsbOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.05" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
<Rectangle Grid.Column="1" Width="18" Height="24" HorizontalAlignment="Right" Margin="0 0 -18 0" Fill="DimGray"></Rectangle>
<Rectangle Grid.Column="0" Width="18" Height="24" HorizontalAlignment="Left" Margin="-18 0 0 0" Fill="DimGray"></Rectangle>
</Grid>
+
+ <ComboBox Visibility="{Binding IsStarted,Converter={StaticResource BooleanToVisibilityInverseConverter}}" ItemsSource="{Binding UsbPorts}" SelectedItem="{Binding SelectedUsbPort,Mode=TwoWay}" VerticalAlignment="Bottom" VerticalContentAlignment="Center" FontSize="12" Foreground="Yellow" BorderThickness="0" Background="Transparent" HorizontalAlignment="Center" Width="100" Margin="10"></ComboBox>
</Grid>
<Grid Grid.Column="1">
- <fa:ImageAwesome Icon="PowerOff" Width="80" Height="80" Foreground="DimGray" Cursor="Hand"></fa:ImageAwesome>
+ <Button Cursor="Hand" Width="90" Height="90" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ToggleStartStopCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="PowerOff" Width="80" Height="80" Cursor="Hand">
+ <fa:ImageAwesome.Style>
+ <Style TargetType="fa:ImageAwesome">
+ <Setter Property="Foreground" Value="DimGray"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsStarted}" Value="True">
+ <Setter Property="Foreground" Value="#49C906"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </fa:ImageAwesome.Style>
+ </fa:ImageAwesome>
+ </StackPanel>
+ </Button>
</Grid>
<Grid Grid.Column="2">
@@ -67,11 +145,79 @@
<ColumnDefinition/>
</Grid.ColumnDefinitions>
- <Ellipse Grid.Column="0" Width="16" Height="16" Fill="Black"></Ellipse>
- <Ellipse Grid.Column="1" Width="16" Height="16" Fill="Black"></Ellipse>
+ <Ellipse Grid.Column="0" Width="16" Height="16">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="Black"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.05" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding UsbOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.10" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <Ellipse Grid.Column="1" Width="16" Height="16">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="Black"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding UsbOn}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation BeginTime="00:00:0.15" Storyboard.TargetProperty="Fill.Color" From="Black" To="Lime" Duration="00:00:0.05" AutoReverse="True"></ColorAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
<Rectangle Grid.Column="0" Width="18" Height="24" HorizontalAlignment="Left" Margin="-18 0 0 0" Fill="DimGray"></Rectangle>
<Rectangle Grid.Column="1" Width="18" Height="24" HorizontalAlignment="Right" Margin="0 0 -18 0" Fill="DimGray"></Rectangle>
</Grid>
+
+ <TextBlock Visibility="{Binding IsWaitingForTCP,Converter={StaticResource BooleanToVisibilityConverter}}" VerticalAlignment="Bottom" Text="Waiting for connection..." HorizontalAlignment="Center" Margin="20" Foreground="DimGray">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="Loaded">
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" AutoReverse="True" Duration="00:00:0.2" RepeatBehavior="Forever"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
</Grid>
</Grid>
</Grid>