/// <summary>
        /// Method to parse the udp response
        /// </summary>
        /// <param name="address"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        internal static async Task <FritzDevice> ParseResponseAsync(IPAddress address, string response)
        {
            FritzDevice device = new FritzDevice();

            device.IPAddress = address;
            device.Location  = device.ParseResponseAsync(response);

            var uriBuilder = new UriBuilder();

            uriBuilder.Scheme = "http";
            uriBuilder.Host   = address.ToString();
            uriBuilder.Port   = device.Location.Port;

            uriBuilder.Port   = await new DeviceInfoClient(uriBuilder.Uri.ToString(), 10000).GetSecurityPortAsync();
            uriBuilder.Scheme = "https";
            device.BaseUrl    = uriBuilder.ToString();

            if (device.Location == null)
            {
                return(null);
            }
            else
            {
                return(device);
            }
        }
        /// <summary>
        /// Method to receive async
        /// </summary>
        /// <param name="client">the udp client</param>
        /// <returns>the result task</returns>
        private async Task ReceiveAsync(UdpClient client, Action <FritzDevice> deviceCallback)
        {
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 1900);

            // delay for 20 seconds
            Task waitTask = Task.Delay(TimeSpan.FromSeconds(10));

            var getDeviceInfoTasks = new List <Task <Tr64Description> >();

            Dictionary <IPAddress, FritzDevice> discovered = new Dictionary <IPAddress, FritzDevice>();

            var tr64DataReader = new Tr64DataReader();

            while (!waitTask.IsCompleted)
            {
                var receiveTask = SafeReceiveAsync(client);

                // check wat for tasks
                Task finishedTask = await Task.WhenAny(receiveTask, waitTask);

                if (finishedTask == receiveTask)
                {
                    UdpReceiveResult result = await receiveTask;

                    // if there is data in buffer read and pars it
                    if (result.Buffer != null && result.Buffer.Length > 0)
                    {
                        string response = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length);

                        // create device by endpoint data
                        FritzDevice device = await FritzDevice.ParseResponseAsync(result.RemoteEndPoint.Address, response);

                        if (!discovered.ContainsKey(result.RemoteEndPoint.Address))
                        {
                            if (device != null && device.Location != null && device.Location.Scheme != "unknown")
                            {
                                // fetch the device info
                                deviceCallback?.Invoke(device);
                                getDeviceInfoTasks.Add(tr64DataReader.ReadDeviceInfoAsync(device));
                                discovered.Add(result.RemoteEndPoint.Address, device);
                            }
                        }
                    }
                }
            }

            if (getDeviceInfoTasks.Count > 0)
            {
                foreach (var task in getDeviceInfoTasks)
                {
                    try
                    {
                        var description = await task;
                        description.Device.ParseTR64Desc(description.Data);
                    } catch (FritzDeviceException e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }