aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/AddressView.xaml
blob: 937cf14ddf73130f0486308ce80df4a2397206cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<UserControl x:Class="Tango.MachineStudio.UsersAndRoles.Views.AddressView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:Tango.MachineStudio.UsersAndRoles.ViewModels"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete"
             xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
             xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Tango.MachineStudio.UsersAndRoles.Views"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type=entities:Address, IsDesignTimeCreatable=False}">
    <Grid>
        <controls:TableGrid>
            <TextBlock Text="COUNTRY"></TextBlock>
            <TextBox Text="{Binding Country}" />
            <TextBlock Text="COUNTRY CODE"></TextBlock>
            <TextBox IsReadOnly="True" Text="{Binding CountryCode}"></TextBox>
            <TextBlock Text="STATE"></TextBlock>
            <TextBox Text="{Binding State}"></TextBox>
            <TextBlock Text="CITY"></TextBlock>
            <TextBox Text="{Binding City}" />
            <TextBlock Text="POSTAL CODE"></TextBlock>
            <TextBox Text="{Binding PostalCode}"></TextBox>
            <TextBlock Text="LOCALITY"></TextBlock>
            <TextBox Text="{Binding Locality}" />
            <TextBlock Text="ADDRESS"></TextBlock>
            <TextBox Text="{Binding AddressString}"></TextBox>
        </controls:TableGrid>
    </Grid>
</UserControl>
{ color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Core.Helpers;
using Tango.Logging;
using Tango.PMR;
using Tango.PMR.Common;
using Tango.PMR.Integration;
using Tango.Settings;
using Tango.Transport.Adapters;

namespace Tango.Integration.ExternalBridge
{
    /// <summary>
    /// Scans for available machines on the local area network and physically connected via USB.
    /// </summary>
    /// <seealso cref="Tango.Core.ExtendedObject" />
    public class ExternalBridgeScanner : ExtendedObject
    {
        private Thread _tcpDiscoveryThread;
        private Thread _usbDiscoveryThread;
        private UdpClient _server;
        private IntegrationSettings _settings;

        private SynchronizedObservableCollection<IExternalBridgeClient> _availableMachines;
        /// <summary>
        /// Gets the available machines.
        /// </summary>
        public SynchronizedObservableCollection<IExternalBridgeClient> AvailableMachines
        {
            get { return _availableMachines; }
            private set { _availableMachines = value; RaisePropertyChangedAuto(); }
        }

        private bool _isStarted;
        /// <summary>
        /// Gets or sets a value indicating whether this instance is started.
        /// </summary>
        public bool IsStarted
        {
            get { return _isStarted; }
            private set { _isStarted = value; RaisePropertyChangedAuto(); }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ExternalBridgeScanner"/> class.
        /// </summary>
        public ExternalBridgeScanner()
        {
            _settings = SettingsManager.Default.GetOrCreate<IntegrationSettings>();
            _server = new UdpClient(_settings.ExternalBridgeServiceDiscoveryPort);
            AvailableMachines = new SynchronizedObservableCollection<IExternalBridgeClient>();
        }

        /// <summary>
        /// Start scanning. (Results will be available through <see cref="AvailableMachines"/>).
        /// </summary>
        public void Start()
        {
            if (!IsStarted)
            {
                LogManager.Log("External bridge scanner started...");

                IsStarted = true;

                foreach (var machine in AvailableMachines.OfType<ExternalBridgeTcpClient>().ToList())
                {
                    AvailableMachines.Remove(machine);
                }

                _tcpDiscoveryThread = new Thread(TcpDiscoveryThreadMethod);
                _tcpDiscoveryThread.IsBackground = true;
                _tcpDiscoveryThread.Start();

                _usbDiscoveryThread = new Thread(UsbDiscoveryThreadMethod);
                _usbDiscoveryThread.IsBackground = true;
                _usbDiscoveryThread.Start();
            }
        }

        /// <summary>
        /// Stops this instance.
        /// </summary>
        public void Stop()
        {
            if (IsStarted)
            {
                IsStarted = false;
                LogManager.Log("External bridge scanner stopped.");
            }
        }

        /// <summary>
        /// USB discovery thread method.
        /// </summary>
        private void UsbDiscoveryThreadMethod()
        {
            while (IsStarted)
            {
                foreach (var device in Transport.Components.ComPortEnumerator.EnumerateComPorts())
                {
                    if (device.Description.Contains(_settings.EmbeddedDeviceName) || !_settings.FilterExternalBridgeUsbMachines)
                    {
                        if (!AvailableMachines.OfType<ExternalBridgeUsbClient>().ToList().Exists(x => x.ComPort == device.Port))
                        {
                            LogManager.Log("Found a new machine via USB " + device.Description);
                            ThreadsHelper.InvokeUINow(() =>
                            {
                                AvailableMachines.Add(new ExternalBridgeUsbClient(device.Port, device.Description, _settings.EmbeddedSerialBaudRate));
                            });
                        }
                    }
                }

                Thread.Sleep(2000);
            }
        }

        /// <summary>
        /// TCP discovery thread method.
        /// </summary>
        [DebuggerStepThrough]
        private void TcpDiscoveryThreadMethod()
        {
            while (IsStarted)
            {
                try
                {
                    var ClientEp = new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort);
                    _server.EnableBroadcast = true;
                    var ClientRequestData = _server.Receive(ref ClientEp);

                    ExternalBridgeUdpDiscoveryPacket packet = ExternalBridgeUdpDiscoveryPacket.Parser.ParseFrom(ClientRequestData);

                    String address = ClientEp.Address.ToString();

                    //validate service existence using TCP connection.
                    try
                    {
                        TcpClient client = new TcpClient();
                        client.Connect(address, _settings.ExternalBridgeServiceDiscoveryPort);
                        client.Dispose();
                    }
                    catch
                    {
                        var disconnected_machine = AvailableMachines.OfType<ExternalBridgeTcpClient>().ToList().FirstOrDefault(x => x.SerialNumber == packet.SerialNumber && x.IPAddress == address);

                        if (disconnected_machine != null)
                        {
                            LogManager.Log("Disconnected machine detected via TCP: " + disconnected_machine.SerialNumber);
                            AvailableMachines.Remove(disconnected_machine);
                        }

                        continue;
                    }

                    if (!AvailableMachines.OfType<ExternalBridgeTcpClient>().ToList().Exists(x => x.SerialNumber == packet.SerialNumber && x.IPAddress == address))
                    {
                        ExternalBridgeTcpClient newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address);

                        LogManager.Log("Found a new machine via TCP " + newMachine.SerialNumber);

                        ThreadsHelper.InvokeUINow(() =>
                        {
                            AvailableMachines.Insert(1, newMachine);
                        });
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex);
                }
            }
        }

        private DateTime ParseDateTime(String dateTime)
        {
            try
            {
                return DateTime.ParseExact(dateTime, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
            }
            catch (Exception)
            {
                return DateTime.Parse(dateTime);
            }
        }

        /// <summary>
        /// Handles the available machines component state changed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        private void Client_StateChanged(object sender, Transport.TransportComponentState e)
        {
            if (e == Transport.TransportComponentState.Failed || e == Transport.TransportComponentState.Disposed)
            {
                LogManager.Log("External bridge client failed or disposed. Removing from available machines...");
                AvailableMachines.Remove(sender as IExternalBridgeClient);
            }
        }
    }
}