From 2daf438fd6902138b4229e21a8d67b02da778599 Mon Sep 17 00:00:00 2001 From: Roy Date: Tue, 20 Dec 2022 13:06:58 +0200 Subject: Modified TCP machines discovery method to MultiCast. --- .../ExternalBridgeUdpDiscoveryPacket.proto | 1 + .../ExternalBridge/ExternalBridgeScanner.cs | 55 +++++++++++++++------- .../ExternalBridge/ExternalBridgeService.cs | 5 +- .../Tango.Integration/IntegrationSettings.cs | 13 +++++ .../ExternalBridgeUdpDiscoveryPacket.cs | 35 ++++++++++++-- .../Tango.Transport/Discovery/DiscoveryMethod.cs | 14 ++++++ .../Discovery/UdpDiscoveryService.cs | 32 ++++++++++++- .../Tango.Transport/Helpers/IPAddressHelper.cs | 31 ++++++++++++ .../Tango.Transport/Tango.Transport.csproj | 2 + 9 files changed, 165 insertions(+), 23 deletions(-) create mode 100644 Software/Visual_Studio/Tango.Transport/Discovery/DiscoveryMethod.cs create mode 100644 Software/Visual_Studio/Tango.Transport/Helpers/IPAddressHelper.cs (limited to 'Software') diff --git a/Software/PMR/Messages/Integration/ExternalBridgeUdpDiscoveryPacket.proto b/Software/PMR/Messages/Integration/ExternalBridgeUdpDiscoveryPacket.proto index d797e6de3..9a65d3818 100644 --- a/Software/PMR/Messages/Integration/ExternalBridgeUdpDiscoveryPacket.proto +++ b/Software/PMR/Messages/Integration/ExternalBridgeUdpDiscoveryPacket.proto @@ -7,4 +7,5 @@ message ExternalBridgeUdpDiscoveryPacket { string Time = 1; string SerialNumber = 2; + string Guid = 3; } \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs index 694502d2e..5e99dd647 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs @@ -23,6 +23,8 @@ using Tango.PMR.Common; using Tango.PMR.Integration; using Tango.Settings; using Tango.Transport.Adapters; +using Tango.Transport.Discovery; +using Tango.Transport.Helpers; namespace Tango.Integration.ExternalBridge { @@ -35,7 +37,6 @@ namespace Tango.Integration.ExternalBridge private Thread _tcpDiscoveryThread; private Thread _usbDiscoveryThread; private Thread _signalRDiscoveryThread; - private UdpClient _server; private IntegrationSettings _settings; private HubConnection _connection; private IHubProxy _proxy; @@ -99,13 +100,6 @@ namespace Tango.Integration.ExternalBridge { LogManager.Log("External bridge scanner started..."); - if (_server == null) - { - _server = new UdpClient(); - _server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - _server.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort)); - } - IsStarted = true; foreach (var machine in AvailableMachines.OfType().ToList()) @@ -209,13 +203,40 @@ namespace Tango.Integration.ExternalBridge { try { - var ClientEp = new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort); - _server.EnableBroadcast = true; - var ClientRequestData = _server.Receive(ref ClientEp); + ExternalBridgeUdpDiscoveryPacket discoveryPacket = null; + String address = null; + + if (_settings.ExternalBridgeDiscoveryMethod == DiscoveryMethod.Multicast) + { + using (UdpClient udpClient = new UdpClient()) + { + udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort)); + udpClient.Ttl = 10; + udpClient.JoinMulticastGroup(IPAddress.Parse(_settings.ExternalBridgeMulticastGroup), IPAddress.Parse(IPAddressHelper.GetLocalIpAddress())); + + var endPoint = new IPEndPoint(IPAddress.Any, 0); + var discoveryData = udpClient.Receive(ref endPoint); - ExternalBridgeUdpDiscoveryPacket packet = ExternalBridgeUdpDiscoveryPacket.Parser.ParseFrom(ClientRequestData); + discoveryPacket = ExternalBridgeUdpDiscoveryPacket.Parser.ParseFrom(discoveryData); + address = endPoint.Address.ToString(); + } + } + else + { + using (UdpClient udpClient = new UdpClient()) + { + udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort)); + var endPoint = new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort); - String address = ClientEp.Address.ToString(); + udpClient.EnableBroadcast = true; + var discoveryData = udpClient.Receive(ref endPoint); + + discoveryPacket = ExternalBridgeUdpDiscoveryPacket.Parser.ParseFrom(discoveryData); + address = endPoint.Address.ToString(); + } + } //validate service existence using TCP connection. try @@ -226,7 +247,7 @@ namespace Tango.Integration.ExternalBridge } catch { - var disconnected_machine = AvailableMachines.OfType().ToList().FirstOrDefault(x => x.SerialNumber == packet.SerialNumber && x.IPAddress == address); + var disconnected_machine = AvailableMachines.OfType().ToList().FirstOrDefault(x => x.SerialNumber == discoveryPacket.SerialNumber && x.IPAddress == address); if (disconnected_machine != null) { @@ -238,14 +259,14 @@ namespace Tango.Integration.ExternalBridge continue; } - if (!AvailableMachines.OfType().ToList().Exists(x => x.SerialNumber == packet.SerialNumber && x.IPAddress == address)) + if (!AvailableMachines.OfType().ToList().Exists(x => x.SerialNumber == discoveryPacket.SerialNumber && x.IPAddress == address)) { ExternalBridgeTcpClient newMachine = null; - var knownMachine = KnownMachines.FirstOrDefault(x => x.SerialNumber == packet.SerialNumber); + var knownMachine = KnownMachines.FirstOrDefault(x => x.SerialNumber == discoveryPacket.SerialNumber); if (knownMachine == null && KnownMachines.Count == 0) { - newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address); + newMachine = new ExternalBridgeTcpClient(discoveryPacket.SerialNumber, address); } else if (knownMachine != null) { diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs index 4218f9e9a..6396774ae 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs @@ -40,6 +40,7 @@ namespace Tango.Integration.ExternalBridge private TcpServer _tcpServer; private int _discovery_port = 8888; //Will be overridden by settings in constructor.. private int _external_bridge_port = 1984; //Will be overridden by settings in constructor.. + private String _multicastAddress = "234.55.66.77"; //Will be overridden by settings in constructor.. private HubConnection _connection; private IHubProxy _proxy; private bool _isSignalRConnected; @@ -199,6 +200,7 @@ namespace Tango.Integration.ExternalBridge _discovery_port = settings.ExternalBridgeServiceDiscoveryPort; _external_bridge_port = settings.ExternalBridgeServicePort; + _multicastAddress = settings.ExternalBridgeMulticastGroup; _tcpServer = new TcpServer(_external_bridge_port); _tcpServer.ClientConnected += _tcpServer_ClientConnected; @@ -234,7 +236,8 @@ namespace Tango.Integration.ExternalBridge _discoveryService = new UdpDiscoveryService(_discovery_port, new ExternalBridgeUdpDiscoveryPacket() { SerialNumber = Machine.SerialNumber, - }); + Guid = Machine.Guid, + }) { MulticastGroupAddress = _multicastAddress }; _discoveryService.BeforeBroadcasting -= _discoverySevice_BeforeBroadcasting; _discoveryService.BeforeBroadcasting += _discoverySevice_BeforeBroadcasting; diff --git a/Software/Visual_Studio/Tango.Integration/IntegrationSettings.cs b/Software/Visual_Studio/Tango.Integration/IntegrationSettings.cs index ce6ace32a..20d0b76e4 100644 --- a/Software/Visual_Studio/Tango.Integration/IntegrationSettings.cs +++ b/Software/Visual_Studio/Tango.Integration/IntegrationSettings.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using Tango.Settings; using Tango.Transport.Adapters; +using Tango.Transport.Discovery; namespace Tango.Integration { @@ -20,6 +21,16 @@ namespace Tango.Integration /// public int ExternalBridgeServiceDiscoveryPort { get; set; } + /// + /// Gets or sets the external bridge multi-cast group address. + /// + public String ExternalBridgeMulticastGroup { get; set; } + + /// + /// Gets or sets the discovery method. + /// + public DiscoveryMethod ExternalBridgeDiscoveryMethod { get; set; } + /// /// Gets or sets the name of the embedded device. /// @@ -42,6 +53,8 @@ namespace Tango.Integration { ExternalBridgeServicePort = 1984; ExternalBridgeServiceDiscoveryPort = 8888; + ExternalBridgeMulticastGroup = "234.55.66.77"; + ExternalBridgeDiscoveryMethod = DiscoveryMethod.Multicast; EmbeddedDeviceName = "Tango USB Serial Port"; FilterExternalBridgeUsbMachines = false; EmbeddedSerialBaudRate = UsbSerialBaudRates.BR_115200; diff --git a/Software/Visual_Studio/Tango.PMR/Integration/ExternalBridgeUdpDiscoveryPacket.cs b/Software/Visual_Studio/Tango.PMR/Integration/ExternalBridgeUdpDiscoveryPacket.cs index df584d5c6..309f95be3 100644 --- a/Software/Visual_Studio/Tango.PMR/Integration/ExternalBridgeUdpDiscoveryPacket.cs +++ b/Software/Visual_Studio/Tango.PMR/Integration/ExternalBridgeUdpDiscoveryPacket.cs @@ -23,13 +23,14 @@ namespace Tango.PMR.Integration { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "CiZFeHRlcm5hbEJyaWRnZVVkcERpc2NvdmVyeVBhY2tldC5wcm90bxIVVGFu", - "Z28uUE1SLkludGVncmF0aW9uIkYKIEV4dGVybmFsQnJpZGdlVWRwRGlzY292", + "Z28uUE1SLkludGVncmF0aW9uIlQKIEV4dGVybmFsQnJpZGdlVWRwRGlzY292", "ZXJ5UGFja2V0EgwKBFRpbWUYASABKAkSFAoMU2VyaWFsTnVtYmVyGAIgASgJ", - "QiEKH2NvbS50d2luZS50YW5nby5wbXIuaW50ZWdyYXRpb25iBnByb3RvMw==")); + "EgwKBEd1aWQYAyABKAlCIQofY29tLnR3aW5lLnRhbmdvLnBtci5pbnRlZ3Jh", + "dGlvbmIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Integration.ExternalBridgeUdpDiscoveryPacket), global::Tango.PMR.Integration.ExternalBridgeUdpDiscoveryPacket.Parser, new[]{ "Time", "SerialNumber" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Integration.ExternalBridgeUdpDiscoveryPacket), global::Tango.PMR.Integration.ExternalBridgeUdpDiscoveryPacket.Parser, new[]{ "Time", "SerialNumber", "Guid" }, null, null, null) })); } #endregion @@ -62,6 +63,7 @@ namespace Tango.PMR.Integration { public ExternalBridgeUdpDiscoveryPacket(ExternalBridgeUdpDiscoveryPacket other) : this() { time_ = other.time_; serialNumber_ = other.serialNumber_; + guid_ = other.guid_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -91,6 +93,17 @@ namespace Tango.PMR.Integration { } } + /// Field number for the "Guid" field. + public const int GuidFieldNumber = 3; + private string guid_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Guid { + get { return guid_; } + set { + guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ExternalBridgeUdpDiscoveryPacket); @@ -106,6 +119,7 @@ namespace Tango.PMR.Integration { } if (Time != other.Time) return false; if (SerialNumber != other.SerialNumber) return false; + if (Guid != other.Guid) return false; return true; } @@ -114,6 +128,7 @@ namespace Tango.PMR.Integration { int hash = 1; if (Time.Length != 0) hash ^= Time.GetHashCode(); if (SerialNumber.Length != 0) hash ^= SerialNumber.GetHashCode(); + if (Guid.Length != 0) hash ^= Guid.GetHashCode(); return hash; } @@ -132,6 +147,10 @@ namespace Tango.PMR.Integration { output.WriteRawTag(18); output.WriteString(SerialNumber); } + if (Guid.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Guid); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -143,6 +162,9 @@ namespace Tango.PMR.Integration { if (SerialNumber.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(SerialNumber); } + if (Guid.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid); + } return size; } @@ -157,6 +179,9 @@ namespace Tango.PMR.Integration { if (other.SerialNumber.Length != 0) { SerialNumber = other.SerialNumber; } + if (other.Guid.Length != 0) { + Guid = other.Guid; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -175,6 +200,10 @@ namespace Tango.PMR.Integration { SerialNumber = input.ReadString(); break; } + case 26: { + Guid = input.ReadString(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.Transport/Discovery/DiscoveryMethod.cs b/Software/Visual_Studio/Tango.Transport/Discovery/DiscoveryMethod.cs new file mode 100644 index 000000000..b1616644b --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/Discovery/DiscoveryMethod.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Transport.Discovery +{ + public enum DiscoveryMethod + { + Multicast, + Broadcast + } +} diff --git a/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryService.cs b/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryService.cs index c37ab7f51..e4ccbe4e9 100644 --- a/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryService.cs +++ b/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryService.cs @@ -3,12 +3,14 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Timers; using Tango.Core; using Tango.PMR.Discovery; +using Tango.Transport.Helpers; using Tango.Transport.Servers; namespace Tango.Transport.Discovery @@ -32,6 +34,11 @@ namespace Tango.Transport.Discovery /// public DiscoveryMessage CurrentDiscoveryMessage { get; set; } + /// + /// Gets or sets the multi-cast group address when using multi-cast discovery method. + /// + public String MulticastGroupAddress { get; set; } + /// /// Gets or sets the interval in which the discovery message will be sent. /// @@ -127,14 +134,15 @@ namespace Tango.Transport.Discovery private void BroadcastDiscoveryPacket() { + //Broadcast try { + BeforeBroadcasting?.Invoke(this, CurrentDiscoveryMessage); + UdpClient client = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, Port); - BeforeBroadcasting?.Invoke(this, CurrentDiscoveryMessage); - byte[] bytes = CurrentDiscoveryMessage.ToByteArray(); client.EnableBroadcast = true; @@ -146,6 +154,26 @@ namespace Tango.Transport.Discovery { LogManager.Log(ex, "Error broadcasting discovery packet."); } + + //Multicast + try + { + UdpClient client = new UdpClient(AddressFamily.InterNetwork); + + IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(MulticastGroupAddress), Port); + + client.JoinMulticastGroup(IPAddress.Parse(MulticastGroupAddress), IPAddress.Parse(IPAddressHelper.GetLocalIpAddress())); + + byte[] bytes = CurrentDiscoveryMessage.ToByteArray(); + + client.Send(bytes, bytes.Length, endPoint); + + client.Close(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error multicasting discovery packet."); + } } } } diff --git a/Software/Visual_Studio/Tango.Transport/Helpers/IPAddressHelper.cs b/Software/Visual_Studio/Tango.Transport/Helpers/IPAddressHelper.cs new file mode 100644 index 000000000..04a15caa3 --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/Helpers/IPAddressHelper.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Transport.Helpers +{ + public static class IPAddressHelper + { + public static string GetLocalIpAddress() + { + foreach (var netI in NetworkInterface.GetAllNetworkInterfaces()) + { + if (netI.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 && + (netI.NetworkInterfaceType != NetworkInterfaceType.Ethernet || + netI.OperationalStatus != OperationalStatus.Up)) continue; + foreach (var uniIpAddrInfo in netI.GetIPProperties().UnicastAddresses.Where(x => netI.GetIPProperties().GatewayAddresses.Count > 0)) + { + + if (uniIpAddrInfo.Address.AddressFamily == AddressFamily.InterNetwork && + uniIpAddrInfo.AddressPreferredLifetime != uint.MaxValue) + return uniIpAddrInfo.Address.ToString(); + } + } + return null; + } + } +} diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index bbe0b3780..c0fac9344 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -107,6 +107,7 @@ + @@ -117,6 +118,7 @@ + -- cgit v1.3.1