aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs
blob: c78f6199eeaacfef7d154f7fe8d4142760a4b5b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Transport.Web;

namespace Tango.PPC.Common.Web
{
    public class UpdateDBRequest : WebRequestMessage
    {
        public String SerialNumber { get; set; }
        public String ApplicationVersion { get; set; }
        public String FirmwareVersion { get; set; }
    }
}
*/ .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 Google.Protobuf;
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Tango.Logging;
using Tango.Transport.Adapters;
using Tango.Transport.Components;
using Tango.Transport.Transporters;

namespace Tango.Transport.Discovery
{
    internal static class UsbComPortWin32
    {
        internal static int dwFlagsAndAttributes = 0x40000000;

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
    }

    /// <summary>
    /// Represents a USB port scanner which will scan all known ports on PC with the specified request and response types. 
    /// </summary>
    /// <typeparam name="TRequest">The type of the request.</typeparam>
    /// <typeparam name="TResponse">The type of the response.</typeparam>
    /// <seealso cref="Tango.Transport.Discovery.ICommunicationScanner{Tango.Transport.Adapters.UsbTransportAdapter, TRequest, TResponse}" />
    public class UsbCommunicationScanner<TRequest, TResponse> : ICommunicationScanner<UsbTransportAdapter, TRequest, TResponse> where TRequest : IMessage where TResponse : IMessage
    {
        public event Action<String> ScanningPort;

        /// <summary>
        /// Gets the baud rate.
        /// </summary>
        public UsbSerialBaudRates BaudRate { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="UsbCommunicationScanner{TRequest, TResponse}"/> class.
        /// </summary>
        /// <param name="baudRate">The baud rate.</param>
        public UsbCommunicationScanner(UsbSerialBaudRates baudRate)
        {
            BaudRate = baudRate;
        }

        /// <summary>
        /// Scans the environment with the specified request while expecting the type of response.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="timeout">The timeout.</param>
        /// <returns></returns>
        public Task<CommunicationScannerResult<UsbTransportAdapter, TResponse>> Scan(TRequest request, TimeSpan timeout)
        {
            var logManager = LogManager.Default;

            logManager.Log("Starting com ports scanning using baud rate " + BaudRate.ToInt32() + "...");

            DateTime startTime = DateTime.Now;
            bool found = false;

            TaskCompletionSource<CommunicationScannerResult<UsbTransportAdapter, TResponse>> source = new TaskCompletionSource<CommunicationScannerResult<UsbTransportAdapter, TResponse>>();

            Task.Factory.StartNew(async () =>
            {
                CommunicationScannerResult<UsbTransportAdapter, TResponse> result = new CommunicationScannerResult<UsbTransportAdapter, TResponse>();

                logManager.Log("Enumerating com ports...");
                var comPorts = ComPortEnumerator.EnumerateComPorts();

                while (!found && DateTime.Now < startTime.Add(timeout))
                {
                    foreach (var port in comPorts)
                    {
                        if (DateTime.Now > startTime.Add(timeout))
                        {
                            break;
                        }

                        logManager.Log("Scanning " + port.ToString() + "...");

                        ScanningPort?.Invoke(port.Port);

                        SafeFileHandle hFile = UsbComPortWin32.CreateFile(@"\\.\" + port.Port, -1073741824, 0, IntPtr.Zero, 3, UsbComPortWin32.dwFlagsAndAttributes, IntPtr.Zero);
                        if (hFile.IsInvalid)
                        {
                            logManager.Log(String.Format("Port {0} is already open or invalid.", port.Port));
                            hFile.Close();
                            continue;
                        }

                        hFile.Close();

                        SerialPort serialPort = new SerialPort(port.Port);

                        try
                        {
                            serialPort.Open();
                            serialPort.Close();
                        }
                        catch (Exception ex)
                        {
                            logManager.Log(ex, "Could not open port " + port.Port);
                            continue;
                        }

                        BasicTransporter transporter = new BasicTransporter(new UsbTransportAdapter(port.Port, BaudRate));

                        try
                        {
                            logManager.Log("Connecting transporter...");
                            await transporter.Connect();
                            logManager.Log("Sending scanning request...");
                            var response = await transporter.SendRequest(request, TimeSpan.FromSeconds(2));

                            if (response is TResponse)
                            {
                                logManager.Log("Response received from " + port.ToString());

                                ITransportAdapter adapter = null;

                                try
                                {
                                    adapter = transporter.Adapter;
                                    logManager.Log("Disconnecting transporter... (keeping adapter)");
                                    transporter.Adapter = null;
                                    await transporter.Disconnect();
                                }
                                catch { }

                                found = true;

                                logManager.Log("Setting scan task result.");
                                source.SetResult(new CommunicationScannerResult<UsbTransportAdapter, TResponse>()
                                {
                                    Adapter = adapter as UsbTransportAdapter,
                                    Response = (TResponse)response,
                                });

                                break;
                            }

                            logManager.Log("Disconnecting transporter...");
                            await transporter.Disconnect();
                        }
                        catch (Exception ex)
                        {
                            try
                            {
                                logManager.Log(ex, "Disconnecting transporter...");
                                await transporter.Disconnect();
                            }
                            catch { }
                        }
                    }
                }

                if (!found)
                {
                    source.SetException(new TimeoutException(logManager.Log("The com port scanning operation had timed out after " + timeout.TotalSeconds + " seconds.")));
                }
            });

            return source.Task;
        }
    }
}