diff --git a/UbntDiscovery/Discovery/BroadcastUdpClient.cs b/UbntDiscovery/Discovery/BroadcastUdpClient.cs
new file mode 100644
index 0000000..5845ecb
--- /dev/null
+++ b/UbntDiscovery/Discovery/BroadcastUdpClient.cs
@@ -0,0 +1,26 @@
+using System.Net;
+using System.Net.Sockets;
+
+namespace UbntDiscovery
+{
+ class BroadcastUdpClient : UdpClient
+ {
+ public BroadcastUdpClient() : base()
+ {
+ //Calls the protected Client property belonging to the UdpClient base class.
+ Socket s = this.Client;
+ //Uses the Socket returned by Client to set an option that is not available using UdpClient.
+ s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
+ s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
+ }
+
+ public BroadcastUdpClient(IPEndPoint ipLocalEndPoint) : base(ipLocalEndPoint)
+ {
+ //Calls the protected Client property belonging to the UdpClient base class.
+ Socket s = this.Client;
+ //Uses the Socket returned by Client to set an option that is not available using UdpClient.
+ s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
+ s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
+ }
+ }
+}
diff --git a/UbntDiscovery/Device.cs b/UbntDiscovery/Discovery/Device.cs
similarity index 81%
rename from UbntDiscovery/Device.cs
rename to UbntDiscovery/Discovery/Device.cs
index 9c9891c..8e49f46 100644
--- a/UbntDiscovery/Device.cs
+++ b/UbntDiscovery/Discovery/Device.cs
@@ -47,7 +47,7 @@ public class Device
{ "ACP", "airCam PRO" }, { "AirCamPRO", "airCam PRO" }, { "AirCamDome", "airCam Dome" }, { "AirCamMini", "airCam Mini" },
{ "AirCam", "airCam" }, { "NVR", "airVision NVR" }, { "ACD", "airCam Dome" }, { "ACM", "airCam Mini" }, { "AC", "airCam" },
{ "TSW-5-POE", "TOUGHSwitch 5 PoE" }, { "TSW-8-POE", "TOUGHSwitch 8 PoE" }, { "TSW-8", "TOUGHSwitch 8" },
- { "TSW-PoE PRO", "TOUGHSwitch PoE PRO" }, { "TSW-PoE", "TOUGHSwitch PoE" } };
+ { "TSW-PoE PRO", "TOUGHSwitch PoE PRO" }, { "TSW-PoE", "TOUGHSwitch PoE" }, { "P5B-400", "M5 NanoBeam 400" } };
public Device()
{
@@ -73,7 +73,9 @@ public String WirelessModeDescription
get
{
if (WirelessMode < WirelessModes.Length)
+ {
return WirelessModes[WirelessMode];
+ }
return String.Format("Unknown {0}", WirelessMode);
}
@@ -99,5 +101,52 @@ public override string ToString()
{
return String.Format("{1}:{0}", Hostname, FirstAddress.IpAddress);
}
+
+ public bool Equals(Device other)
+ {
+ if (Hostname != other.Hostname)
+ {
+ return false;
+ }
+ if (Platform != other.Platform)
+ {
+ return false;
+ }
+ if (Firmware != other.Firmware)
+ {
+ return false;
+ }
+ if (SSID != other.SSID)
+ {
+ return false;
+ }
+
+ if (Uptime != other.Uptime)
+ {
+ return false;
+ }
+ if (WirelessMode != other.WirelessMode)
+ {
+ return false;
+ }
+
+ int addressCount = Addresses.Count;
+ if (addressCount != other.Addresses.Count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < addressCount; i++)
+ {
+ DeviceAddress a = Addresses[i];
+ DeviceAddress b = other.Addresses[i];
+ if (!a.Equals(b))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
}
diff --git a/UbntDiscovery/DeviceAddress.cs b/UbntDiscovery/Discovery/DeviceAddress.cs
similarity index 100%
rename from UbntDiscovery/DeviceAddress.cs
rename to UbntDiscovery/Discovery/DeviceAddress.cs
diff --git a/UbntDiscovery/DeviceDiscovery.cs b/UbntDiscovery/Discovery/DeviceDiscovery.cs
similarity index 79%
rename from UbntDiscovery/DeviceDiscovery.cs
rename to UbntDiscovery/Discovery/DeviceDiscovery.cs
index ec85e53..73534b2 100644
--- a/UbntDiscovery/DeviceDiscovery.cs
+++ b/UbntDiscovery/Discovery/DeviceDiscovery.cs
@@ -22,17 +22,11 @@ protected virtual void OnDeviceDiscovered(Device e)
public Boolean IsScanning { get; set; }
- ///
- /// Endpoint to listen
- ///
- private IPEndPoint _EP1;
-
///
/// Endpoint to broadcast
///
private IPEndPoint _EP2;
- private HashSet _PacketHash;
///
/// Packet data to broadcast
@@ -42,20 +36,19 @@ protected virtual void OnDeviceDiscovered(Device e)
public DeviceDiscovery()
{
IsScanning = false;
- _PacketHash = new HashSet();
- _EP1 = new IPEndPoint(IPAddress.Any, 2048);
_EP2 = new IPEndPoint(IPAddress.Broadcast, 10001);
}
- public async Task DiscoveryAsync(CancellationToken ct)
+ public async Task DiscoveryAsync(CancellationToken ct, IPAddress interfaceAddress)
{
-
- var udpClient = new UdpClient(_EP1);
- udpClient.EnableBroadcast = true;
+ IPEndPoint interfaceEndpoint = new IPEndPoint(interfaceAddress, 2048);
+ var udpClient = new BroadcastUdpClient(interfaceEndpoint);
+ //udpClient.EnableBroadcast = true;
await udpClient.SendAsync(_Datagram, _Datagram.Length, _EP2);
udpClient.EnableBroadcast = false;
ct.Register(() => udpClient.Close() );
-
+
+ HashSet packetHash = new HashSet();
while (!ct.IsCancellationRequested)
{
@@ -73,15 +66,16 @@ public async Task DiscoveryAsync(CancellationToken ct)
DiscoveryPacket dpack = new DiscoveryPacket(receiveResult.Buffer);
Device device = dpack.DecodePacket();
- Boolean result = _PacketHash.Add(Utils.CalculateHash(receiveResult.Buffer));
+ Boolean result = packetHash.Add(Utils.CalculateHash(receiveResult.Buffer));
if (result)
+ {
OnDeviceDiscovered(device);
-
+ }
}
udpClient.Close();
- _PacketHash.Clear();
+ packetHash.Clear();
}
diff --git a/UbntDiscovery/DiscoveryPacket.cs b/UbntDiscovery/Discovery/DiscoveryPacket.cs
similarity index 100%
rename from UbntDiscovery/DiscoveryPacket.cs
rename to UbntDiscovery/Discovery/DiscoveryPacket.cs
diff --git a/UbntDiscovery/MainWindowModel.cs b/UbntDiscovery/MainWindowModel.cs
index 77d3068..76a808e 100644
--- a/UbntDiscovery/MainWindowModel.cs
+++ b/UbntDiscovery/MainWindowModel.cs
@@ -1,5 +1,8 @@
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Net;
+using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@@ -9,18 +12,18 @@ namespace UbntDiscovery
{
public class MainWindowModel
{
- public ObservableCollection Devices { get; private set; }
+ public ObservableCollection Devices { get; private set; }
public DeviceDiscovery DeviceDiscovery { get; private set; }
public MainWindow MainWindow { get; private set; }
private CancellationTokenSource _cts;
- private Task discoveryTask;
public MainWindowModel(MainWindow mainWindow)
{
Devices = new ObservableCollection();
MainWindow = mainWindow;
DeviceDiscovery = new DeviceDiscovery();
- DeviceDiscovery.DeviceDiscovered += DeviceDiscovery_DeviceDiscovered;
+ DeviceDiscovery.DeviceDiscovered += DeviceDiscovery_DeviceDiscovered;
+ _cts = new CancellationTokenSource();
}
private void DeviceDiscovery_DeviceDiscovered(Device device)
@@ -30,26 +33,38 @@ private void DeviceDiscovery_DeviceDiscovered(Device device)
public async Task ScanAsync()
{
- if (discoveryTask != null && (discoveryTask.Status == TaskStatus.WaitingForActivation || discoveryTask.Status == TaskStatus.Running) )
- {
- _cts.Cancel();
- Devices.Clear();
- }
+ _cts.Cancel();
+ Devices.Clear();
try
{
var cts = new CancellationTokenSource();
_cts = cts;
- discoveryTask = DeviceDiscovery.DiscoveryAsync(_cts.Token).ContinueWith((t) => cts.Dispose());
- await discoveryTask;
+ String strHostName = Dns.GetHostName();
+ // Find host by name
+ IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
+
+ // Enumerate IP addresses
+ List tasks = new List();
+ foreach (IPAddress ipaddress in iphostentry.AddressList)
+ {
+ if (ipaddress.AddressFamily == AddressFamily.InterNetwork)
+ {
+ Task discoveryTask = DeviceDiscovery.DiscoveryAsync(cts.Token, ipaddress);
+ tasks.Add(discoveryTask);
+ }
+ }
+ foreach (Task discoveryTask in tasks)
+ {
+ await discoveryTask;
+ }
+ cts.Dispose();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
-
-
}
public void ClearDevices()
@@ -62,13 +77,15 @@ public void AddDevice(Device device)
{
MainWindow.Dispatcher.Invoke(() =>
{
+ foreach (Device existingDevice in Devices)
+ {
+ if (existingDevice.Equals(device))
+ {
+ return;
+ }
+ }
Devices.Add(device);
-
});
}
-
-
-
-
}
}
diff --git a/UbntDiscovery/UbntDiscovery.csproj b/UbntDiscovery/UbntDiscovery.csproj
index 993a5d3..857b776 100644
--- a/UbntDiscovery/UbntDiscovery.csproj
+++ b/UbntDiscovery/UbntDiscovery.csproj
@@ -67,9 +67,10 @@
MSBuild:Compile
Designer
-
-
-
+
+
+
+
MSBuild:Compile
@@ -79,7 +80,7 @@
App.xaml
Code
-
+
MainWindow.xaml
Code