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; } } }
/// <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); } }