From ba85a4094f1365f137f4f35cf62ff310476c52d9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 30 Jan 2015 12:58:38 -0500 Subject: [PATCH] add xbox 360 dlna services --- MediaBrowser.Api/Dlna/DlnaServerService.cs | 48 +++++- .../Dlna/IMediaReceiverRegistrar.cs | 7 + .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 4 + .../MediaReceiverRegistrar/ControlHandler.cs | 43 +++++ .../MediaReceiverRegistrar.cs | 39 +++++ .../MediaReceiverRegistrarXmlBuilder.cs | 78 +++++++++ .../ServiceActionListBuilder.cs | 154 ++++++++++++++++++ .../Server/DescriptionXmlBuilder.cs | 9 + .../ApplicationHost.cs | 4 + 10 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 MediaBrowser.Controller/Dlna/IMediaReceiverRegistrar.cs create mode 100644 MediaBrowser.Dlna/MediaReceiverRegistrar/ControlHandler.cs create mode 100644 MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs create mode 100644 MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs create mode 100644 MediaBrowser.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs index 2383017c6..3de8bac49 100644 --- a/MediaBrowser.Api/Dlna/DlnaServerService.cs +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -1,6 +1,5 @@ using MediaBrowser.Controller.Dlna; using ServiceStack; -using ServiceStack.Text.Controller; using ServiceStack.Web; using System; using System.Collections.Generic; @@ -31,6 +30,12 @@ namespace MediaBrowser.Api.Dlna { } + [Route("/Dlna/mediareceiverregistrar/mediareceiverregistrar.xml", "GET", Summary = "Gets dlna mediareceiverregistrar xml")] + [Route("/Dlna/mediareceiverregistrar/mediareceiverregistrar", "GET", Summary = "Gets dlna mediareceiverregistrar xml")] + public class GetMediaReceiverRegistrar + { + } + [Route("/Dlna/contentdirectory/{UuId}/control", "POST", Summary = "Processes a control request")] public class ProcessContentDirectoryControlRequest : IRequiresRequestStream { @@ -49,6 +54,22 @@ namespace MediaBrowser.Api.Dlna public Stream RequestStream { get; set; } } + [Route("/Dlna/mediareceiverregistrar/{UuId}/control", "POST", Summary = "Processes a control request")] + public class ProcessMediaReceiverRegistrarControlRequest : IRequiresRequestStream + { + [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string UuId { get; set; } + + public Stream RequestStream { get; set; } + } + + [Route("/Dlna/mediareceiverregistrar/{UuId}/events", Summary = "Processes an event subscription request")] + public class ProcessMediaReceiverRegistrarEventRequest + { + [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string UuId { get; set; } + } + [Route("/Dlna/contentdirectory/{UuId}/events", Summary = "Processes an event subscription request")] public class ProcessContentDirectoryEventRequest { @@ -75,12 +96,14 @@ namespace MediaBrowser.Api.Dlna private readonly IDlnaManager _dlnaManager; private readonly IContentDirectory _contentDirectory; private readonly IConnectionManager _connectionManager; + private readonly IMediaReceiverRegistrar _mediaReceiverRegistrar; - public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager) + public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar) { _dlnaManager = dlnaManager; _contentDirectory = contentDirectory; _connectionManager = connectionManager; + _mediaReceiverRegistrar = mediaReceiverRegistrar; } public object Get(GetDescriptionXml request) @@ -97,6 +120,13 @@ namespace MediaBrowser.Api.Dlna return ResultFactory.GetResult(xml, "text/xml"); } + public object Get(GetMediaReceiverRegistrar request) + { + var xml = _mediaReceiverRegistrar.GetServiceXml(GetRequestHeaders()); + + return ResultFactory.GetResult(xml, "text/xml"); + } + public object Get(GetConnnectionManager request) { var xml = _connectionManager.GetServiceXml(GetRequestHeaders()); @@ -104,13 +134,20 @@ namespace MediaBrowser.Api.Dlna return ResultFactory.GetResult(xml, "text/xml"); } - public async Task Post(ProcessContentDirectoryControlRequest request) + public async Task Post(ProcessMediaReceiverRegistrarControlRequest request) { var response = await PostAsync(request.RequestStream, _contentDirectory).ConfigureAwait(false); return ResultFactory.GetResult(response.Xml, "text/xml"); } + public async Task Post(ProcessContentDirectoryControlRequest request) + { + var response = await PostAsync(request.RequestStream, _mediaReceiverRegistrar).ConfigureAwait(false); + + return ResultFactory.GetResult(response.Xml, "text/xml"); + } + public async Task Post(ProcessConnectionManagerControlRequest request) { var response = await PostAsync(request.RequestStream, _connectionManager).ConfigureAwait(false); @@ -171,6 +208,11 @@ namespace MediaBrowser.Api.Dlna return ProcessEventRequest(_connectionManager); } + public object Any(ProcessMediaReceiverRegistrarEventRequest request) + { + return ProcessEventRequest(_mediaReceiverRegistrar); + } + private object ProcessEventRequest(IEventManager eventManager) { var subscriptionId = GetHeader("SID"); diff --git a/MediaBrowser.Controller/Dlna/IMediaReceiverRegistrar.cs b/MediaBrowser.Controller/Dlna/IMediaReceiverRegistrar.cs new file mode 100644 index 000000000..6b76783a5 --- /dev/null +++ b/MediaBrowser.Controller/Dlna/IMediaReceiverRegistrar.cs @@ -0,0 +1,7 @@ + +namespace MediaBrowser.Controller.Dlna +{ + public interface IMediaReceiverRegistrar : IEventManager, IUpnpService + { + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 867d9b0c5..238cdbc9e 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -111,6 +111,7 @@ + diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 7871946cb..aed4ef421 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -64,6 +64,10 @@ + + + + Code diff --git a/MediaBrowser.Dlna/MediaReceiverRegistrar/ControlHandler.cs b/MediaBrowser.Dlna/MediaReceiverRegistrar/ControlHandler.cs new file mode 100644 index 000000000..d1f701711 --- /dev/null +++ b/MediaBrowser.Dlna/MediaReceiverRegistrar/ControlHandler.cs @@ -0,0 +1,43 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Dlna.Server; +using MediaBrowser.Dlna.Service; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.MediaReceiverRegistrar +{ + public class ControlHandler : BaseControlHandler + { + public ControlHandler(IServerConfigurationManager config, ILogger logger) : base(config, logger) + { + } + + protected override IEnumerable> GetResult(string methodName, Headers methodParams) + { + if (string.Equals(methodName, "IsAuthorized", StringComparison.OrdinalIgnoreCase)) + return HandleIsAuthorized(); + if (string.Equals(methodName, "IsValidated", StringComparison.OrdinalIgnoreCase)) + return HandleIsValidated(); + + throw new ResourceNotFoundException("Unexpected control request name: " + methodName); + } + + private IEnumerable> HandleIsAuthorized() + { + return new Headers(true) + { + { "Result", "1" } + }; + } + + private IEnumerable> HandleIsValidated() + { + return new Headers(true) + { + { "Result", "1" } + }; + } + } +} diff --git a/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs b/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs new file mode 100644 index 000000000..a3b2bcee0 --- /dev/null +++ b/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs @@ -0,0 +1,39 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Dlna.Service; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.MediaReceiverRegistrar +{ + public class MediaReceiverRegistrar : BaseService, IMediaReceiverRegistrar, IDisposable + { + private readonly IServerConfigurationManager _config; + + public MediaReceiverRegistrar(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config) + : base(logger, httpClient) + { + _config = config; + } + + public string GetServiceXml(IDictionary headers) + { + return new MediaReceiverRegistrarXmlBuilder().GetXml(); + } + + public ControlResponse ProcessControlRequest(ControlRequest request) + { + return new ControlHandler( + _config, + Logger) + .ProcessControlRequest(request); + } + + public void Dispose() + { + + } + } +} diff --git a/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs b/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs new file mode 100644 index 000000000..cb1fdcecb --- /dev/null +++ b/MediaBrowser.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs @@ -0,0 +1,78 @@ +using MediaBrowser.Dlna.Common; +using MediaBrowser.Dlna.Service; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.MediaReceiverRegistrar +{ + public class MediaReceiverRegistrarXmlBuilder + { + public string GetXml() + { + return new ServiceXmlBuilder().GetXml(new ServiceActionListBuilder().GetActions(), + GetStateVariables()); + } + + private IEnumerable GetStateVariables() + { + var list = new List(); + + list.Add(new StateVariable + { + Name = "AuthorizationGrantedUpdateID", + DataType = "ui4", + SendsEvents = true + }); + + list.Add(new StateVariable + { + Name = "A_ARG_TYPE_DeviceID", + DataType = "string", + SendsEvents = false + }); + + list.Add(new StateVariable + { + Name = "AuthorizationDeniedUpdateID", + DataType = "ui4", + SendsEvents = true + }); + + list.Add(new StateVariable + { + Name = "ValidationSucceededUpdateID", + DataType = "ui4", + SendsEvents = true + }); + + list.Add(new StateVariable + { + Name = "A_ARG_TYPE_RegistrationRespMsg", + DataType = "bin.base64", + SendsEvents = false + }); + + list.Add(new StateVariable + { + Name = "A_ARG_TYPE_RegistrationReqMsg", + DataType = "bin.base64", + SendsEvents = false + }); + + list.Add(new StateVariable + { + Name = "ValidationRevokedUpdateID", + DataType = "ui4", + SendsEvents = true + }); + + list.Add(new StateVariable + { + Name = "A_ARG_TYPE_Result", + DataType = "int", + SendsEvents = false + }); + + return list; + } + } +} diff --git a/MediaBrowser.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs b/MediaBrowser.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs new file mode 100644 index 000000000..40fc954f7 --- /dev/null +++ b/MediaBrowser.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs @@ -0,0 +1,154 @@ +using MediaBrowser.Dlna.Common; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.MediaReceiverRegistrar +{ + public class ServiceActionListBuilder + { + public IEnumerable GetActions() + { + var list = new List + { + GetIsValidated(), + GetIsAuthorized(), + //GetRegisterDevice(), + //GetGetAuthorizationDeniedUpdateID(), + //GetGetAuthorizationGrantedUpdateID(), + //GetGetValidationRevokedUpdateID(), + //GetGetValidationSucceededUpdateID() + }; + + return list; + } + + private ServiceAction GetIsValidated() + { + var action = new ServiceAction + { + Name = "IsValidated" + }; + + action.ArgumentList.Add(new Argument + { + Name = "DeviceID", + Direction = "in" + }); + + action.ArgumentList.Add(new Argument + { + Name = "Result", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetIsAuthorized() + { + var action = new ServiceAction + { + Name = "IsAuthorized" + }; + + action.ArgumentList.Add(new Argument + { + Name = "DeviceID", + Direction = "in" + }); + + action.ArgumentList.Add(new Argument + { + Name = "Result", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetRegisterDevice() + { + var action = new ServiceAction + { + Name = "RegisterDevice" + }; + + action.ArgumentList.Add(new Argument + { + Name = "RegistrationReqMsg", + Direction = "in" + }); + + action.ArgumentList.Add(new Argument + { + Name = "RegistrationRespMsg", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetGetValidationSucceededUpdateID() + { + var action = new ServiceAction + { + Name = "GetValidationSucceededUpdateID" + }; + + action.ArgumentList.Add(new Argument + { + Name = "ValidationSucceededUpdateID", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetGetAuthorizationDeniedUpdateID() + { + var action = new ServiceAction + { + Name = "GetAuthorizationDeniedUpdateID" + }; + + action.ArgumentList.Add(new Argument + { + Name = "AuthorizationDeniedUpdateID", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetGetValidationRevokedUpdateID() + { + var action = new ServiceAction + { + Name = "GetValidationRevokedUpdateID" + }; + + action.ArgumentList.Add(new Argument + { + Name = "ValidationRevokedUpdateID", + Direction = "out" + }); + + return action; + } + + private ServiceAction GetGetAuthorizationGrantedUpdateID() + { + var action = new ServiceAction + { + Name = "GetAuthorizationGrantedUpdateID" + }; + + action.ArgumentList.Add(new Argument + { + Name = "AuthorizationGrantedUpdateID", + Direction = "out" + }); + + return action; + } + } +} diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index 545da7a86..186c7e10b 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -212,6 +212,15 @@ namespace MediaBrowser.Dlna.Server EventSubUrl = "/dlna/connectionmanager/" + _serverUdn + "/events" }); + list.Add(new DeviceService + { + ServiceType = "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", + ServiceId = "urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar", + ScpdUrl = "/dlna/mediareceiverregistrar/mediareceiverregistrar.xml", + ControlUrl = "/dlna/mediareceiverregistrar/" + _serverUdn + "/control", + EventSubUrl = "/dlna/mediareceiverregistrar/" + _serverUdn + "/events" + }); + return list; } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 5726e1755..1ded0c254 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -44,6 +44,7 @@ using MediaBrowser.Dlna; using MediaBrowser.Dlna.ConnectionManager; using MediaBrowser.Dlna.ContentDirectory; using MediaBrowser.Dlna.Main; +using MediaBrowser.Dlna.MediaReceiverRegistrar; using MediaBrowser.LocalMetadata.Providers; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.MediaEncoding.Encoder; @@ -496,6 +497,9 @@ namespace MediaBrowser.Server.Startup.Common var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager); RegisterSingleInstance(contentDirectory); + var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager); + RegisterSingleInstance(mediaRegistrar); + NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager); RegisterSingleInstance(NotificationManager);