Example #1
0
        /// <summary>
        ///   Discover devices in LAN
        /// </summary>
        /// <returns></returns>
        public static async IAsyncEnumerable <Device> DiscoverAndEnumerateAsync(CancellationToken?cancel = null)
        {
            List <Task <IEnumerable <Device> > > tasks = NetworkInterface.GetAllNetworkInterfaces()
                                                         .Where(networkInterface => networkInterface.OperationalStatus == OperationalStatus.Up)
                                                         .Select(networkInterface => DeviceLocator.DiscoverAsync(networkInterface, deviceFoundReporter: null)).ToList();

            Dictionary <string, Device> allUniqueDevices = new Dictionary <string, Device>();

            while (tasks.Count != 0)
            {
                Task <IEnumerable <Device> > completedTask = await Task.WhenAny(tasks);

                tasks.Remove(completedTask);

                IEnumerable <Device> devices = await completedTask;

                foreach (Device device in devices)
                {
                    if (!allUniqueDevices.ContainsKey(device.Hostname))
                    {
                        allUniqueDevices.Add(device.Hostname, device);
                        yield return(device);
                    }
                }

                if (cancel.HasValue && cancel.Value.IsCancellationRequested)
                {
                    break;
                }
            }
        }
Example #2
0
        private static IEnumerable <Device> CheckSocketForDevices(IEnumerable <MulticastIPAddressInformation> multicastIPAddresses, UnicastIPAddressInformation ip, IProgress <Device> deviceFoundCallback, int retryCount)
        {
            // Use hash table for faster lookup, than List.Contains
            var devices = new Dictionary <string, Device>();

            for (int count = 0; count < retryCount; count++)
            {
                foreach (MulticastIPAddressInformation mca in multicastIPAddresses)
                {
                    try
                    {
                        using (var ssdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
                        {
                            var multicastIPEndpoint = new IPEndPoint(mca.Address, 1982);
                            DeviceLocator.InitializeSocket(multicastIPEndpoint, ip, ssdpSocket);
                            DeviceLocator.GetDevicesFromSocket(multicastIPEndpoint, deviceFoundCallback, ssdpSocket, devices);
                        }
                    }
                    catch (SocketException ex)
                    {
                        //return devices.Values.ToList();
                    }
                }
            }

            return(devices.Values.ToList());
        }
Example #3
0
        public static async Task <List <Device> > Discover(NetworkInterface preferredInterface)
        {
            List <Task <List <Device> > > tasks = DeviceLocator.CreateDiscoverTasks(preferredInterface, DeviceLocator.MaxRetryCount);

            List <Device>[] result = await Task.WhenAll(tasks);

            return(result
                   .SelectMany(devices => devices)
                   .GroupBy(d => d.Hostname)
                   .Select(g => g.First())
                   .ToList());
        }
Example #4
0
        private static void GetDevicesFromSocket(IPEndPoint multicastIPEndpoint, IProgress <Device> deviceFoundCallback, Socket ssdpSocket, Dictionary <string, Device> devices)
        {
            ssdpSocket.SendTo(
                Encoding.ASCII.GetBytes(string.Format(DeviceLocator._ssdpMessage, multicastIPEndpoint.Address)),
                SocketFlags.None,
                multicastIPEndpoint
                );

            var stopWatch = Stopwatch.StartNew();

            try
            {
                while (stopWatch.Elapsed < TimeSpan.FromSeconds(1))
                {
                    try // Catch socket read exception
                    {
                        int available = ssdpSocket.Available;

                        if (available > 0)
                        {
                            var buffer            = new byte[available];
                            int numberOfBytesRead = ssdpSocket.Receive(buffer, SocketFlags.None);

                            if (numberOfBytesRead > 0)
                            {
                                string response = Encoding.UTF8.GetString(buffer.Take(numberOfBytesRead).ToArray());
                                Device device   = DeviceLocator.GetDeviceInformationFromSsdpMessage(response);

                                if (!devices.ContainsKey(device.Hostname))
                                {
                                    devices.Add(device.Hostname, device);
                                    deviceFoundCallback?.Report(device);
                                }
                            }
                        }
                    }
                    catch (SocketException)
                    {
                        // Ignore SocketException and continue polling
                    }

                    Thread.Sleep(TimeSpan.FromMilliseconds(10));
                }
            }
            finally
            {
                stopWatch.Stop();
            }
        }
Example #5
0
        /// <summary>
        ///   Create Discovery tasks for a specific Network Interface
        /// </summary>
        /// <param name="netInterface"></param>
        /// <param name="deviceFoundCallback"></param>
        /// <returns></returns>
        private static async Task <IEnumerable <Device> > SearchNetworkForDevicesAsync(NetworkInterface netInterface, IProgress <Device> deviceFoundCallback)
        {
            if (netInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
                netInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
            {
                int retryCount = DeviceLocator.MaxRetryCount;
                IEnumerable <MulticastIPAddressInformation> multicastAddresses = DeviceLocator.GetMulticastIPAddressesForDiscovery(netInterface.GetIPProperties().MulticastAddresses);

                return(await Task.Run(
                           () => netInterface.GetIPProperties().UnicastAddresses
                           .Where(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
                           .AsParallel()
                           .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                           .SelectMany(ip => DeviceLocator.CheckSocketForDevices(multicastAddresses, ip, deviceFoundCallback, retryCount))
                           .ToList()));
            }

            return(new List <Device>());
        }
Example #6
0
        public static async Task <List <Device> > Discover()
        {
            var tasks      = new List <Task <List <Device> > >();
            int retryCount = DeviceLocator.MaxRetryCount;

            foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()
                     .Where(n => n.OperationalStatus == OperationalStatus.Up))
            {
                tasks.AddRange(DeviceLocator.CreateDiscoverTasks(ni, retryCount));
            }


            List <Device>[] result = await Task.WhenAll(tasks);

            return(result
                   .SelectMany(devices => devices)
                   .GroupBy(d => d.Hostname)
                   .Select(g => g.First())
                   .ToList());
        }
Example #7
0
 /// <summary>
 ///   Discover devices in a specific Network Interface
 /// </summary>
 /// <param name="networkInterface"></param>
 /// <param name="deviceFoundReporter"></param>
 /// <returns></returns>
 public static async Task <IEnumerable <Device> > DiscoverAsync(
     NetworkInterface networkInterface,
     IProgress <Device> deviceFoundReporter) =>
 await DeviceLocator.SearchNetworkForDevicesAsync(networkInterface, deviceFoundReporter);
Example #8
0
 /// <summary>
 ///   Discover devices in a specific Network Interface
 /// </summary>
 /// <param name="networkInterface"></param>
 /// <returns></returns>
 public static async Task <IEnumerable <Device> > DiscoverAsync(NetworkInterface networkInterface) =>
 await DeviceLocator.DiscoverAsync(networkInterface, null);
Example #9
0
        /// <summary>
        ///   Discover devices in LAN
        /// </summary>
        /// <returns></returns>
        public static async Task <IEnumerable <Device> > DiscoverAsync(IProgress <Device> deviceFoundReporter)
        {
            IEnumerable <Task <IEnumerable <Device> > > tasks = NetworkInterface.GetAllNetworkInterfaces()
                                                                .Where(networkInterface => networkInterface.OperationalStatus == OperationalStatus.Up)
                                                                .Select(networkInterface => DeviceLocator.DiscoverAsync(networkInterface, deviceFoundReporter));

            IEnumerable <Device>[] result = await Task.WhenAll(tasks);

            return(result
                   .SelectMany(devices => devices)
                   .GroupBy(d => d.Hostname)
                   .Select(g => g.First())
                   .ToList());
        }
Example #10
0
 /// <summary>
 ///   Discover devices in LAN
 /// </summary>
 /// <returns></returns>
 public static async Task <IEnumerable <Device> > DiscoverAsync() =>
 await DeviceLocator.DiscoverAsync(deviceFoundReporter : null);
Example #11
0
        private static List <Task <List <Device> > > CreateDiscoverTasks(NetworkInterface netInterface, int retryCount)
        {
            var devices = new ConcurrentDictionary <string, Device>();
            var tasks   = new List <Task <List <Device> > >();

            if (netInterface.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 &&
                netInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet)
            {
                return(tasks);
            }

            foreach (UnicastIPAddressInformation ip in netInterface.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                {
                    continue;
                }

                for (var count = 0; count < retryCount; count++)
                {
                    Task <List <Device> > t = Task.Run(
                        async() =>
                    {
                        var stopWatch = new Stopwatch();
                        try
                        {
                            using (var ssdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
                            {
                                Blocking = false,
                                Ttl = 1,
                                UseOnlyOverlappedIO = true,
                                MulticastLoopback = false
                            })
                            {
                                ssdpSocket.Bind(new IPEndPoint(ip.Address, 0));
                                ssdpSocket.SetSocketOption(
                                    SocketOptionLevel.IP,
                                    SocketOptionName.AddMembership,
                                    new MulticastOption(DeviceLocator._multicastEndPoint.Address));

                                ssdpSocket.SendTo(
                                    DeviceLocator._ssdpDiagram,
                                    SocketFlags.None,
                                    DeviceLocator._multicastEndPoint);

                                stopWatch.Start();
                                while (stopWatch.Elapsed < TimeSpan.FromSeconds(1))
                                {
                                    try
                                    {
                                        int available = ssdpSocket.Available;

                                        if (available > 0)
                                        {
                                            var buffer = new byte[available];
                                            int i      = ssdpSocket.Receive(buffer, SocketFlags.None);

                                            if (i > 0)
                                            {
                                                string response = Encoding.UTF8.GetString(buffer.Take(i).ToArray());
                                                Device device   = DeviceLocator.GetDeviceInformationFromSsdpMessage(response);

                                                //add only if no device already matching
                                                if (devices.TryAdd(device.Hostname, device))
                                                {
                                                    DeviceLocator.OnDeviceFound?.Invoke(null, new DeviceFoundEventArgs(device));
                                                }
                                            }
                                        }
                                    }
                                    catch (SocketException)
                                    {
                                        // Continue polling
                                    }

                                    await Task.Delay(TimeSpan.FromMilliseconds(10));
                                }

                                stopWatch.Stop();
                            }
                        }
                        catch (SocketException)
                        {
                            return(devices.Values.ToList());
                        }
                        finally
                        {
                            stopWatch.Stop();
                        }

                        return(devices.Values.ToList());
                    });

                    tasks.Add(t);
                }
            }

            return(tasks);
        }