Exemplo n.º 1
0
        /// <summary>
        /// Locate bridges by sending a specific multicast packet and listening to any reply
        /// <para>
        /// The multicast packet is sent every second and any endpoint responding is investigated to see if it is a Hue Bridge</para>
        /// </summary>
        /// <param name="multicastAddress">Multicast address to send to</param>
        /// <param name="multicastPort">Multicast port to send to</param>
        /// <param name="localPort">Local port to send from and listen to</param>
        /// <param name="discoveryMessageContent">The content to send</param>
        /// <param name="cancellationToken">Token to cancel the search</param>
        /// <returns>List of bridge IPs found</returns>
        protected async Task <IEnumerable <LocatedBridge> > LocateBridgesAsync(
            IPAddress multicastAddress, int multicastPort, int localPort, byte[] discoveryMessageContent, CancellationToken cancellationToken)
        {
            var discoveredBridges = new ConcurrentDictionary <string, LocatedBridge>();

            // We will bind to all network interfaces having a private IPv4
            List <Socket> socketList = NetworkInterfaceExtensions.GetAllUpNetworkInterfacesFirstPrivateIPv4()
                                       // Create socket for each address remaining (and asking for a random available port)
                                       .Select(info => CreateSocketForMulticastUDPIPv4(new IPEndPoint(info.Address, localPort), multicastAddress))
                                       .ToList();

            try
            {
                foreach (Socket socket in socketList)
                {
                    // Spin up a new thread to listen to this socket
                    new Thread(() => ListenSocketAndCheckEveryEndpoint(socket, discoveredBridges)).Start();
                }

                do
                {
                    // Send multicast discovery message for each socket
                    foreach (Socket socket in socketList)
                    {
                        socket.SendTo(discoveryMessageContent, SocketFlags.None, new IPEndPoint(multicastAddress, multicastPort));
                    }

                    // Wait 1 seconds (can be shorter if cancelled)
                    await Task.Delay(TimeSpan.FromMilliseconds(1000), cancellationToken);
                }while (!cancellationToken.IsCancellationRequested);
            }
            catch (TaskCanceledException)
            {
                // Cancellation requested
            }
            finally
            {
                // Close socket (which will end thread) then dispose unmanaged resource
                foreach (Socket socket in socketList)
                {
                    socket.Close();
                    socket.Dispose();
                }
            }

            return(discoveredBridges.Select(x => x.Value).ToList());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Locate bridges
        /// </summary>
        /// <param name="cancellationToken">Token to cancel the search</param>
        /// <returns>List of bridge IPs found</returns>
        public override async Task <IEnumerable <LocatedBridge> > LocateBridgesAsync(CancellationToken cancellationToken)
        {
            _discoveredBridges = new ConcurrentDictionary <string, LocatedBridge>();

            // Get all IPv4 private unicast addresses from all network interfaces that are up
            List <IPAddress> networkIps = NetworkInterfaceExtensions.GetAllUpNetworkInterfacesFirstPrivateIPv4()
                                          // For each interface, get all IP from this network
                                          .SelectMany(info => info.Address.GetAllIPv4FromNetwork(info.IPv4Mask))
                                          // Eventually filter common ones
                                          .Distinct()
                                          .ToList();

            if (networkIps.Count > 0)
            {
                // Run in another thread so we won't block the UI
                await Task.Run(() =>
                {
                    try
                    {
                        // We'll use the Parallel.ForEach methods so the work will be distributed on all core
                        ParallelOptions parallelOptions = new ParallelOptions
                        {
                            CancellationToken      = cancellationToken,
                            MaxDegreeOfParallelism = Environment.ProcessorCount,
                        };

                        Parallel.ForEach(networkIps, parallelOptions, (ip) => CheckIP(ip, cancellationToken));
                    }
                    catch (OperationCanceledException)
                    {
                        // Cancellation requested
                    }
                });
            }
            else
            {
                // No IP found
            }

            return(_discoveredBridges.Select(x => x.Value).ToList());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Locate bridges
        /// </summary>
        /// <param name="cancellationToken">Token to cancel the search</param>
        /// <returns>List of bridge IPs found</returns>
        public override async Task <IEnumerable <LocatedBridge> > LocateBridgesAsync(CancellationToken cancellationToken)
        {
            var discoveredBridges = new ConcurrentDictionary <string, LocatedBridge>();

            // Get all IPv4 private unicast addresses from all network interfaces that are up
            List <IPAddress> networkIps = NetworkInterfaceExtensions.GetAllUpNetworkInterfacesFirstPrivateIPv4()
                                          // For each interface, get all IP from this network
                                          .SelectMany(info => info.Address.GetAllIPv4FromNetwork(info.IPv4Mask))
                                          // Eventually filter common ones
                                          .Distinct()
                                          .ToList();

            if (networkIps.Count > 0)
            {
                // Run in another thread so we won't block the UI
                await Task.Run(() =>
                {
                    try
                    {
                        // We'll use the Parallel.ForEach methods so the work will be distributed on all core
                        ParallelOptions parallelOptions = new ParallelOptions
                        {
                            CancellationToken      = cancellationToken,
                            MaxDegreeOfParallelism = Environment.ProcessorCount,
                        };

                        Parallel.ForEach(networkIps, parallelOptions, (ip) =>
                        {
                            // Check if an IP is a Hue Bridge by checking its descriptor
                            // Note that the timeout here is important:
                            // - if small, can speedup significantly the searching, but may miss an answer if the Hue Bridge took too much time to answer
                            // - if big, will be sure to check thoroughly each IP, but the search can be slower
                            string serialNumber = CheckHueDescriptor(ip, TimeSpan.FromMilliseconds(1000), cancellationToken).Result;

                            if (!string.IsNullOrEmpty(serialNumber))
                            {
                                var locatedBridge = new LocatedBridge()
                                {
                                    IpAddress = ip.ToString(),
                                    BridgeId  = serialNumber,
                                };
                                if (discoveredBridges.TryAdd(ip.ToString(), locatedBridge))
                                {
                                    OnBridgeFound(locatedBridge);
                                }
                            }
                            else
                            {
                                // Not a hue bridge
                            }
                        });
                    }
                    catch (OperationCanceledException)
                    {
                        // Cancellation requested
                    }
                });
            }
            else
            {
                // No IP found
            }

            return(discoveredBridges.Select(x => x.Value).ToList());
        }
        public void TestInterframeGap()
        {
            long speedInBitsPerSecond;

            double gapNanos;

            double gapMicros;

            System.TimeSpan microTime;

            //Todo, method with various types of interfaces
            foreach (var nif in NetworkInterfaceExtensions.GetNetworkInterface(System.Net.NetworkInformation.NetworkInterfaceType.Ethernet, System.Net.NetworkInformation.NetworkInterfaceType.Wireless80211))
            {
                //Speed changes for Wifi between calls but speed always shows 100000 would need interop to ask stack what the current speed or max speed is...
                speedInBitsPerSecond = nif.Speed;

                //Calulcate the gap in Nanoseconds
                gapNanos = NetworkInterfaceExtensions.GetInterframeGapNanoseconds(nif);

                //Caulcate the same gap but in Microseconds
                gapMicros = NetworkInterfaceExtensions.GetInterframeGapMicroseconds(nif);

                //Calulcate a TimeSpan which represents the total Microseconds.
                microTime = TimeSpanExtensions.FromMicroseconds((double)gapMicros);

                //Rounding ...
                //if (TimeSpanExtensions.TotalMicroseconds(microTime) != gapMicros) throw new System.Exception("TotalMicroseconds");

                //Verify that the conversion was correct
                if ((int)TimeSpanExtensions.TotalMicroseconds(microTime) != (int)gapMicros)
                {
                    throw new System.Exception("TotalMicroseconds");
                }

                //Calculate how much difference there is when converting from the microsecond term to the nano second term.
                double diff = gapMicros * TimeSpanExtensions.NanosecondsPerMicrosecond - TimeSpanExtensions.TotalNanoseconds(microTime);

                //If there was any difference
                if (diff > 0)
                {
                    //if that difference is greater than 1 nano second throw an exception
                    if (diff > NetworkInterfaceExtensions.MinimumInterframeGapBits)
                    {
                        throw new System.Exception("TotalNanoseconds");
                    }
                    else
                    {
                        System.Console.WriteLine("μs to ns conversion Different By: " + diff);
                    }
                }

                //Write the information
                System.Console.WriteLine(string.Format("Name: {0}, Type: {1}, \r\nSpeed Bits Per Second: {2}, \r\nGapMicros:{3} GapNanos{4}, MicroTime:{5}", nif.Name, nif.NetworkInterfaceType, speedInBitsPerSecond, gapMicros, gapNanos, microTime));

                System.Console.WriteLine("Speed In MBytes Per Second: " + NetworkInterfaceExtensions.GetSpeedInMBytesPerSecond(nif));

                //Verify results
                switch (speedInBitsPerSecond)
                {
                //1Gpbs
                case 10000000000:
                {
                    if (gapNanos != 9.6)
                    {
                        throw new System.Exception("Invalid InterframeGap");
                    }
                    break;
                }

                //1Gpbs
                case 1000000000:
                {
                    if (gapNanos != 96)
                    {
                        throw new System.Exception("Invalid InterframeGap");
                    }
                    break;
                }

                //100 Mbps
                case 100000000:
                {
                    if (gapNanos != 960)
                    {
                        throw new System.Exception("Invalid InterframeGap");
                    }
                    break;
                }

                //10 Mbps
                case 10000000:
                {
                    if (gapNanos != 9600)
                    {
                        throw new System.Exception("Invalid InterframeGap");
                    }
                    break;
                }

                //1 Mbps
                case 1000000:
                {
                    if (gapNanos != 96000)
                    {
                        throw new System.Exception("Invalid InterframeGap");
                    }
                    break;
                }
                }
            }

            ////Todo, fix overflow for all speeds.
            //for (int i = 1; i <= 1000000000; ++i)
            //{
            //    speedInBitsPerSecond = i * 100;

            //    gapNanos = NetworkInterfaceExtensions.CaulculateInterframeGapNanoseconds(speedInBitsPerSecond);

            //    gapMicros = (long)(gapNanos * TimeSpanExtensions.NanosecondsPerMicrosecond);

            //    microTime = TimeSpanExtensions.FromMicroseconds((double)gapMicros);

            //    if ((int)TimeSpanExtensions.TotalMicroseconds(microTime) != (int)gapMicros) throw new System.Exception("TotalMicroseconds");

            //    //Calculate how much difference there is when converting from the microsecond term to the nano second term.
            //    double diff = gapMicros * TimeSpanExtensions.NanosecondsPerMicrosecond - TimeSpanExtensions.TotalNanoseconds(microTime);

            //    if (diff > 0)
            //    {
            //        //if that difference is greater than 1 nano second throw an exception
            //        if (diff > TimeSpanExtensions.NanosecondsPerTick) throw new System.Exception("TotalNanoseconds");
            //        else System.Console.WriteLine("μs to ns conversion Different By: " + diff);
            //    }

            //    System.Console.WriteLine(string.Format("Name{0}, Type: {1}, Speed: {2}, GapMicros:{3} GapNanos{4}, MicroTime:{5}", "N/A", "N/A", speedInBitsPerSecond, gapMicros, gapNanos, microTime));

            //    System.Console.WriteLine("Speed In MBytes Per Second: " + speedInBitsPerSecond / TimeSpanExtensions.NanosecondsPerMillisecond);
            //}
        }