protected void UnicastSearchForST(string st, IPEndPoint endPoint)
        {
            SimpleHTTPRequest request = new SimpleHTTPRequest("M-SEARCH", "*");

            request.SetHeader("HOST", NetworkHelper.IPEndPointToString(endPoint));
            request.SetHeader("MAN", "\"ssdp:discover\"");
            request.SetHeader("ST", st);
            request.SetHeader("USER-AGENT", UPnPConfiguration.UPnPMachineInfoHeader);
            lock (_cpData.SyncObj)
            {
                foreach (EndpointConfiguration config in _cpData.Endpoints)
                {
                    if (config.AddressFamily != endPoint.AddressFamily)
                    {
                        continue;
                    }
                    Socket socket = config.SSDP_UDP_UnicastSocket;
                    if (socket == null)
                    {
                        return;
                    }
                    byte[] bytes = request.Encode();
                    NetworkHelper.SendData(socket, endPoint, bytes, 1); // The server will send the answer to the same socket as we use to send
                    return;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Sends a NOTIFY packet "ssdp:alive" to all UPnP endpoints.
        /// </summary>
        /// <param name="NT">Notification type.</param>
        /// <param name="USN">Unique Service Name.</param>
        /// <param name="rootDevice">Root device for that the message should be send.</param>
        public void SendMessage(string NT, string USN, DvDevice rootDevice)
        {
            SimpleHTTPRequest response = new SimpleHTTPRequest("NOTIFY", "*");

            response.SetHeader("CACHE-CONTROL", "max-age = " + _serverData.AdvertisementExpirationTime);
            response.SetHeader("NT", NT);
            response.SetHeader("NTS", "ssdp:alive");
            response.SetHeader("SERVER", UPnPConfiguration.UPnPMachineInfoHeader);
            response.SetHeader("USN", USN);
            response.SetHeader("BOOTID.UPNP.ORG", _serverData.BootId.ToString());
            // Currently, we don't support SEARCHPORT.UPNP.ORG function and header

            foreach (EndpointConfiguration config in _serverData.UPnPEndPoints)
            {
                if (config.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    response.SetHeader("OPT", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01");
                    response.SetHeader("01-NLS", _serverData.BootId.ToString());
                }
                response.SetHeader("CONFIGID.UPNP.ORG", config.ConfigId.ToString());
                IPEndPoint ep = new IPEndPoint(config.SSDPMulticastAddress, UPnPConsts.SSDP_MULTICAST_PORT);
                response.SetHeader("HOST", NetworkHelper.IPEndPointToString(ep));
                if (config.SSDPUsesSpecialSearchPort)
                {
                    response.SetHeader("SEARCHPORT.UPNP.ORG", config.SSDPSearchPort.ToString());
                }
                response.SetHeader("LOCATION", config.GetRootDeviceDescriptionURL(rootDevice));
                byte[] bytes = response.Encode();
                NetworkHelper.MulticastMessage(config.SSDP_UDP_UnicastSocket, config.SSDPMulticastAddress, bytes);
            }
        }
        protected void SendMulticastEventNotification(DvService service, IEnumerable <DvStateVariable> variables)
        {
            DvDevice      device        = service.ParentDevice;
            EventingState eventingState = _serverData.GetMulticastEventKey(service);
            // First cluster variables by multicast event level so we can put variables of the same event level into a single message
            IDictionary <string, ICollection <DvStateVariable> > variablesByLevel =
                new Dictionary <string, ICollection <DvStateVariable> >();

            foreach (DvStateVariable variable in variables)
            {
                ICollection <DvStateVariable> variablesCollection;
                if (!variablesByLevel.TryGetValue(variable.MulticastEventLevel, out variablesCollection))
                {
                    variablesByLevel[variable.MulticastEventLevel] = variablesCollection = new List <DvStateVariable>();
                }
                variablesCollection.Add(variable);
            }
            foreach (KeyValuePair <string, ICollection <DvStateVariable> > varByLevel in variablesByLevel)
            {
                // Use a maximum cluster size of GENA_MAX_MULTICAST_EVENT_VAR_COUNT to keep UDP message small
                ICollection <IList <DvStateVariable> > variableClusters = CollectionUtils.Cluster(
                    varByLevel.Value, UPnPConsts.GENA_MAX_MULTICAST_EVENT_VAR_COUNT);
                foreach (IList <DvStateVariable> cluster in variableClusters)
                {
                    foreach (DvStateVariable variable in cluster)
                    {
                        eventingState.UpdateModerationData(variable);
                    }
                    eventingState.IncEventKey();
                    byte[] bodyData = UPnPConsts.UTF8_NO_BOM.GetBytes(GENAMessageBuilder.BuildEventNotificationMessage(
                                                                          cluster, false)); // Albert TODO: Is it correct not to force the simple string equivalent for extended data types here?
                    SimpleHTTPRequest request = new SimpleHTTPRequest("NOTIFY", "*");
                    request.SetHeader("CONTENT-LENGTH", bodyData.Length.ToString());
                    request.SetHeader("CONTENT-TYPE", "text/xml; charset=\"utf-8\"");
                    request.SetHeader("USN", device.UDN + "::" + service.ServiceTypeVersion_URN);
                    request.SetHeader("SVCID", service.ServiceId);
                    request.SetHeader("NT", "upnp:event");
                    request.SetHeader("NTS", "upnp:propchange");
                    request.SetHeader("SEQ", eventingState.EventKey.ToString());
                    request.SetHeader("LVL", varByLevel.Key);
                    request.SetHeader("BOOTID.UPNP.ORG", _serverData.BootId.ToString());

                    foreach (EndpointConfiguration config in _serverData.UPnPEndPoints)
                    {
                        IPEndPoint ep = new IPEndPoint(config.GENAMulticastAddress, UPnPConsts.GENA_MULTICAST_PORT);
                        request.SetHeader("HOST", NetworkHelper.IPEndPointToString(ep));
                        request.MessageBody = bodyData;
                        byte[] bytes = request.Encode();
                        NetworkHelper.SendData(config.GENA_UDP_Socket, ep, bytes, 1);
                    }
                }
            }
        }
        protected void MulticastSearchForST(string st)
        {
            SimpleHTTPRequest request = new SimpleHTTPRequest("M-SEARCH", "*");

            request.SetHeader("MAN", "\"ssdp:discover\"");
            request.SetHeader("MX", UPnPConfiguration.SEARCH_MX.ToString());
            request.SetHeader("ST", st);
            request.SetHeader("USER-AGENT", UPnPConfiguration.UPnPMachineInfoHeader);
            lock (_cpData.SyncObj)
            {
                foreach (EndpointConfiguration config in _cpData.Endpoints)
                {
                    IPEndPoint ep = new IPEndPoint(config.SSDPMulticastAddress, UPnPConsts.SSDP_MULTICAST_PORT);
                    request.SetHeader("HOST", NetworkHelper.IPEndPointToString(ep));
                    Socket socket = config.SSDP_UDP_UnicastSocket;
                    if (socket == null)
                    {
                        continue;
                    }
                    byte[] bytes = request.Encode();
                    NetworkHelper.MulticastMessage(socket, config.SSDPMulticastAddress, bytes); // The server will send the answer to the same socket as we use to send
                }
            }
        }
        /// <summary>
        /// Sends a NOTIFY packet "ssdp:byebye" to all UPnP endpoints.
        /// </summary>
        /// <param name="NT">Notification type.</param>
        /// <param name="USN">Unique Service Name.</param>
        /// <param name="rootDevice">Root device for that the message should be send.</param>
        public void SendMessage(string NT, string USN, DvDevice rootDevice)
        {
            SimpleHTTPRequest response = new SimpleHTTPRequest("NOTIFY", "*");

            response.SetHeader("NT", NT);
            response.SetHeader("NTS", "ssdp:byebye");
            response.SetHeader("USN", USN);
            response.SetHeader("BOOTID.UPNP.ORG", _serverData.BootId.ToString());
            // Currently, we don't support SEARCHPORT.UPNP.ORG function and header

            foreach (EndpointConfiguration config in _serverData.UPnPEndPoints)
            {
                if (config.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    response.SetHeader("OPT", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01");
                    response.SetHeader("01-NLS", _serverData.BootId.ToString());
                }
                response.SetHeader("CONFIGID.UPNP.ORG", config.ConfigId.ToString());
                IPEndPoint ep = new IPEndPoint(config.SSDPMulticastAddress, UPnPConsts.SSDP_MULTICAST_PORT);
                response.SetHeader("HOST", NetworkHelper.IPEndPointToString(ep));
                byte[] bytes = response.Encode();
                NetworkHelper.MulticastMessage(config.SSDP_UDP_UnicastSocket, config.SSDPMulticastAddress, bytes);
            }
        }