private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint) { var rootDevice = device.ToRootDevice(); var additionalheaders = FormatCustomHeadersForResponse(device); string message; if (device.Weemo) { message = String.Format(WeemoSearchResponseMessageFormat, String.Format("CACHE-CONTROL: max-age={0}", rootDevice.CacheLifetime.TotalSeconds), DateTime.UtcNow.ToString("r"), rootDevice.Location, rootDevice.SerialNumber, searchTarget, uniqueServiceName); } else { message = String.Format(DeviceSearchResponseMessageFormat, CacheControlHeaderFromTimeSpan(rootDevice), searchTarget, uniqueServiceName, rootDevice.Location, _OSName, _OSVersion, ServerVersion, DateTime.UtcNow.ToString("r"), additionalheaders); } _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint); WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device); }
private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint) { var rootDevice = device.ToRootDevice(); var message = String.Format(DeviceSearchResponseMessageFormat, CacheControlHeaderFromTimeSpan(rootDevice), searchTarget, uniqueServiceName, rootDevice.Location, _OSName, _OSVersion, ServerVersion, DateTime.UtcNow.ToString("r") ); _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint); WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device); }
private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint) { var rootDevice = device.ToRootDevice(); var additionalheaders = FormatCustomHeadersForResponse(device); var message = String.Format(DeviceSearchResponseMessageFormat, CacheControlHeaderFromTimeSpan(rootDevice), searchTarget, uniqueServiceName, rootDevice.Location, _OSName, _OSVersion, ServerVersion, DateTime.UtcNow.ToString("r"), additionalheaders ); _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint); LogDeviceEventVerbose(String.Format("Sent search response ({0}) to {1}", uniqueServiceName, endPoint.ToString()), device); }
private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint) { if (String.IsNullOrEmpty(searchTarget)) { _Log.LogWarning(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString())); return; } _Log.LogInfo(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget)); if (IsDuplicateSearchRequest(searchTarget, endPoint)) { Log.LogWarning("Search Request is Duplicate, ignoring."); return; } //Wait on random interval up to MX, as per SSDP spec. //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header (strict mode only). If over 120, assume random value between 0 and 120. //Using 16 as minimum as that's often the minimum system clock frequency anyway. int maxWaitInterval = 0; if (String.IsNullOrEmpty(mx)) { //Windows Explorer is poorly behaved and doesn't supply an MX header value. if (IsWindowsExplorerSupportEnabled) { mx = "1"; } else { _Log.LogWarning("Search Request ignored due to missing MX header. Set StandardsMode to relaxed to respond to these requests."); return; } } if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) { return; } if (maxWaitInterval > 120) { maxWaitInterval = _Random.Next(0, 120); } //Do not block synchronously as that may tie up a threadpool thread for several seconds. TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) => { //Copying devices to local array here to avoid threading issues/enumerator exceptions. IEnumerable <SsdpDevice> devices = null; devices = GetDevicesMatchingSearchTarget(searchTarget, devices); if (devices != null) { SendSearchResponses(searchTarget, endPoint, devices); } else { _Log.LogWarning("Sending search responses for 0 devices (no matching targets)."); } }); }
private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint) { if (String.IsNullOrEmpty(searchTarget)) { WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString())); return; } WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget)); if (IsDuplicateSearchRequest(searchTarget, endPoint)) { WriteTrace("Search Request is Duplicate, ignoring."); return; } //Wait on random interval up to MX, as per SSDP spec. //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120. //Using 16 as minimum as that's often the minimum system clock frequency anyway. int maxWaitInterval = 0; if (String.IsNullOrEmpty(mx)) { //Windows Explorer is poorly behaved and doesn't supply an MX header value. if (this.SupportPnpRootDevice) { mx = "1"; } else { return; } } if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) { return; } if (maxWaitInterval > 120) { maxWaitInterval = _Random.Next(0, 120); } //Do not block synchronously as that may tie up a threadpool thread for several seconds. TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) => { //Copying devices to local array here to avoid threading issues/enumerator exceptions. IEnumerable <SsdpDevice> devices = null; lock (_Devices) { if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0) { devices = GetAllDevicesAsFlatEnumerable().ToArray(); } else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)) { devices = _Devices.ToArray(); } else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase)) { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); } else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase)) { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); } } if (devices != null) { WriteTrace(String.Format("Sending {0} search responses", devices.Count())); foreach (var device in devices) { SendDeviceSearchResponses(device, endPoint); } } else { WriteTrace(String.Format("Sending 0 search responses.")); } }); }
private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint) { if (String.IsNullOrEmpty(searchTarget)) { WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString())); return; } WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget)); if (IsDuplicateSearchRequest(searchTarget, endPoint)) { WriteTrace("Search Request is Duplicate, ignoring."); return; } //Wait on random interval up to MX, as per SSDP spec. //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120. //Using 16 as minimum as that's often the minimum system clock frequency anyway. int maxWaitInterval = 0; if (String.IsNullOrEmpty(mx)) { //Windows Explorer is poorly behaved and doesn't supply an MX header value. if (this.SupportPnpRootDevice) mx = "1"; else return; } if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) return; if (maxWaitInterval > 120) maxWaitInterval = _Random.Next(0, 120); //Do not block synchronously as that may tie up a threadpool thread for several seconds. TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) => { //Copying devices to local array here to avoid threading issues/enumerator exceptions. IEnumerable<SsdpDevice> devices = null; lock (_Devices) { if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0) devices = GetAllDevicesAsFlatEnumerable().ToArray(); else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)) devices = _Devices.ToArray(); else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase)) devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase)) devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); } if (devices != null) { WriteTrace(String.Format("Sending {0} search responses", devices.Count())); foreach (var device in devices) { SendDeviceSearchResponses(device, endPoint); } } else WriteTrace(String.Format("Sending 0 search responses.")); }); }
private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint) { if (device is SsdpHueBridgeDevice) { var hueDevice = device as SsdpHueBridgeDevice; var messageHeader = String.Format(SsdpHueBridgeDevice.HUE_RESPONSE, hueDevice.HttpServerIpAddress, hueDevice.HttpServerPort, hueDevice.HttpServerOptionalSubFolder, hueDevice.HueBridgeId ); var message1 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST1, hueDevice.HueUuid); Debug.WriteLine("Sending packet 1: " + message1); var message2 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST2, hueDevice.HueUuid); Debug.WriteLine("Sending packet 2:" + message2); var message3 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST3, hueDevice.HueUuid); Debug.WriteLine("Sending packet 3: " + message3); _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message1), endPoint); _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message2), endPoint); _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message3), endPoint); } else { var rootDevice = device.ToRootDevice(); var additionalheaders = FormatCustomHeadersForResponse(device); var message = String.Format(DeviceSearchResponseMessageFormat, CacheControlHeaderFromTimeSpan(rootDevice), searchTarget, uniqueServiceName, rootDevice.Location, _OSName, _OSVersion, ServerVersion, DateTime.UtcNow.ToString("r"), additionalheaders ); _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint); } LogDeviceEventVerbose(String.Format("Sent search response ({0}) to {1}", uniqueServiceName, endPoint.ToString()), device); }