Esempio n. 1
0
        public static SsdpDevice ParseBroadcastResponse(IPAddress endpoint, string data)
        {
            // parse http response header
            var pairs = data
                        .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                        .Skip(1)
                        .Select(line => line.Split(new[] { ":" }, 2, StringSplitOptions.None))
                        .Where(parts => parts.Length == 2)
                        .ToDictionary(parts => parts[0].ToLowerInvariant().Trim(), parts => parts[1].Trim());

            var device = new SsdpDevice();

            device.RemoteEndPoint = endpoint;

            string location;

            if (pairs.TryGetValue("location", out location))
            {
                UriBuilder uriBuilder = null;
                Uri        uri        = null;
                if (Uri.TryCreate(location, UriKind.Absolute, out uri))
                {
                    uriBuilder = new UriBuilder(uri);
                }
                else
                {
                    uriBuilder        = new UriBuilder();
                    uriBuilder.Host   = location;
                    uriBuilder.Scheme = "unknown";
                }
                device.Location = uriBuilder.Uri;
            }
            else
            {
                return(null);
            }

            string server;

            if (pairs.TryGetValue("server", out server))
            {
                device.Server = server;
            }

            string st;

            if (pairs.TryGetValue("st", out st))
            {
                device.ServiceType = st;
            }

            string usn;

            if (pairs.TryGetValue("usn", out usn))
            {
                device.UniqueServiceName = usn;
            }

            return(device);
        }
Esempio n. 2
0
        private async Task FetchDeviceInfo(SsdpDevice device, CancellationToken cancelToken)
        {
            try
            {
                var httpRequest = WebRequest.CreateHttp(device.Location);
                httpRequest.Timeout = (int)Math.Round(_replyWait.TotalMilliseconds);

                cancelToken.Register(() => { try { httpRequest.Abort(); } catch { } });

                using (var response = (HttpWebResponse)(await httpRequest.GetResponseAsync()))
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (var responseStream = response.GetResponseStream())
                            using (var responseReader = new StreamReader(responseStream, Encoding.UTF8))
                            {
                                var data = await responseReader.ReadToEndAsync();

                                var deviceInfo = SsdpDeviceInfo.ParseDeviceResponse(data);
                                device.Info = deviceInfo;
                            }
                    }
                }
            }
            catch (ArgumentException) { }
            catch (WebException) { }
            catch (SocketException) { }
            catch (ObjectDisposedException) { }
            catch (OperationCanceledException) { }
            catch (Exception ex)
            {
#if DEBUG
                Console.WriteLine(ex);
#endif
            }

            _deviceFoundCallback?.Invoke(device);
        }
Esempio n. 3
0
        private async Task ReceiveServicer(UdpClient client)
        {
            var endpoint = SSDP_RECEIVE_ENDPOINT;

            var replyWaitTask = _replyWait.TotalMilliseconds > 0 ? Task.Delay(_replyWait) : new TaskCompletionSource <object>().Task;

            List <Task> fetchDeviceInfoTasks = new List <Task>();

            while (!_isCancelled && !replyWaitTask.IsCompleted)
            {
                try
                {
                    var receiveTask  = SafeReceiveAsync(client);
                    var finishedTask = await Task.WhenAny(receiveTask, _cancelTask.Task, replyWaitTask);

                    if (finishedTask == receiveTask)
                    {
                        var asyncResult = await receiveTask;
                        if (asyncResult.Buffer == null)
                        {
                            continue;
                        }
                        var received = receiveTask.Result;
                        if (received.Buffer != null && received.Buffer.Length > 0)
                        {
                            var responseData = Encoding.ASCII.GetString(received.Buffer, 0, received.Buffer.Length);

                            var device = SsdpDevice.ParseBroadcastResponse(received.RemoteEndPoint.Address, responseData);
                            if (device != null)
                            {
                                if (_foundLocations.TryAdd(device.Location, device))
                                {
                                    if (device.Location.Scheme != "unknown")
                                    {
                                        fetchDeviceInfoTasks.Add(FetchDeviceInfo(device, _cancelTokenSrc.Token));
                                    }
                                    else
                                    {
                                        _deviceFoundCallback?.Invoke(device);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        ObserveUdpTaskException(receiveTask);
                    }
                }
                catch (SocketException) { }
                catch (ObjectDisposedException) { }
                catch (OperationCanceledException) { }
                catch (Exception ex)
                {
#if DEBUG
                    Console.WriteLine(ex);
                    throw ex;
#endif
                }
            }

            if (fetchDeviceInfoTasks.Count > 0)
            {
                await Task.WhenAll(fetchDeviceInfoTasks);
            }
        }