Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions UbntDiscovery/Discovery/BroadcastUdpClient.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
51 changes: 50 additions & 1 deletion UbntDiscovery/Device.cs → UbntDiscovery/Discovery/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -73,7 +73,9 @@ public String WirelessModeDescription
get
{
if (WirelessMode < WirelessModes.Length)
{
return WirelessModes[WirelessMode];
}

return String.Format("Unknown {0}", WirelessMode);
}
Expand All @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,11 @@ protected virtual void OnDeviceDiscovered(Device e)

public Boolean IsScanning { get; set; }

/// <summary>
/// Endpoint to listen
/// </summary>
private IPEndPoint _EP1;

/// <summary>
/// Endpoint to broadcast
/// </summary>
private IPEndPoint _EP2;

private HashSet<ulong> _PacketHash;

/// <summary>
/// Packet data to broadcast
Expand All @@ -42,20 +36,19 @@ protected virtual void OnDeviceDiscovered(Device e)
public DeviceDiscovery()
{
IsScanning = false;
_PacketHash = new HashSet<ulong>();
_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<ulong> packetHash = new HashSet<ulong>();

while (!ct.IsCancellationRequested)
{
Expand All @@ -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();

}

Expand Down
51 changes: 34 additions & 17 deletions UbntDiscovery/MainWindowModel.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -9,18 +12,18 @@ namespace UbntDiscovery
{
public class MainWindowModel
{
public ObservableCollection<Device> Devices { get; private set; }
public ObservableCollection <Device> 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<Device>();
MainWindow = mainWindow;
DeviceDiscovery = new DeviceDiscovery();
DeviceDiscovery.DeviceDiscovered += DeviceDiscovery_DeviceDiscovered;
DeviceDiscovery.DeviceDiscovered += DeviceDiscovery_DeviceDiscovered;
_cts = new CancellationTokenSource();
}

private void DeviceDiscovery_DeviceDiscovered(Device device)
Expand All @@ -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<Task> tasks = new List<Task>();
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()
Expand All @@ -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);

});
}




}
}
9 changes: 5 additions & 4 deletions UbntDiscovery/UbntDiscovery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="DeviceAddress.cs" />
<Compile Include="DeviceDiscovery.cs" />
<Compile Include="DiscoveryPacket.cs" />
<Compile Include="Discovery\BroadcastUdpClient.cs" />
<Compile Include="Discovery\DeviceAddress.cs" />
<Compile Include="Discovery\DeviceDiscovery.cs" />
<Compile Include="Discovery\DiscoveryPacket.cs" />
<Compile Include="Utils.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
Expand All @@ -79,7 +80,7 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Device.cs" />
<Compile Include="Discovery\Device.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down