示例#1
0
        private static void ParseDeviceList(String XML, int startLine, ref UPnPDevice RetVal)
        {
            StringReader MyString = new StringReader(XML);
            XmlTextReader XMLDoc = new XmlTextReader(MyString);
            UPnPDevice EmbeddedDevice = null;
            int embededLine;

            try
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                if (XMLDoc.LocalName == "deviceList")
                {
                    XMLDoc.Read();
                    XMLDoc.MoveToContent();

                    while (XMLDoc.LocalName != "deviceList" && !XMLDoc.EOF)
                    {
                        if (XMLDoc.LocalName == "device")
                        {
                            EmbeddedDevice = new UPnPDevice();
                            EmbeddedDevice.IsRoot = false;
                            EmbeddedDevice.BaseURL = RetVal.BaseURL;
                            embededLine = XMLDoc.LineNumber;
                            //ParseDevice("<device>\r\n" + XMLDoc.ReadInnerXml() + "</device>", startLine + embededLine, ref EmbeddedDevice);
                            ParseDevice(XMLDoc.ReadOuterXml(), startLine + embededLine, ref EmbeddedDevice);
                            RetVal.AddDevice(EmbeddedDevice);
                        }
                        if (!XMLDoc.IsStartElement() && XMLDoc.LocalName != "deviceList")
                        {
                            XMLDoc.Read();
                            XMLDoc.MoveToContent();
                        }
                    }
                }
            }
            catch (XMLParsingException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new XMLParsingException("Invalid DeviceList XML near line ", (startLine + XMLDoc.LineNumber), XMLDoc.LinePosition, ex);
            }
        }
        private static void ParseDeviceList(String XML, ref UPnPDevice RetVal)
        {
            StringReader MyString = new StringReader(XML);
            XmlTextReader XMLDoc = new XmlTextReader(MyString);
            UPnPDevice EmbeddedDevice = null;

            XMLDoc.Read();
            XMLDoc.MoveToContent();

            if (XMLDoc.LocalName == "deviceList")
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                while (XMLDoc.LocalName != "deviceList" && !XMLDoc.EOF)
                {
                    if (XMLDoc.LocalName == "device")
                    {
                        EmbeddedDevice = new UPnPDevice();
                        EmbeddedDevice.IsRoot = false;
                        EmbeddedDevice.BaseURL = RetVal.BaseURL;
                        ParseDevice("<device>\r\n" + XMLDoc.ReadInnerXml() + "</device>", ref EmbeddedDevice);
                        RetVal.AddDevice(EmbeddedDevice);
                    }
                    if (!XMLDoc.IsStartElement() && XMLDoc.LocalName != "deviceList")
                    {
                        XMLDoc.Read();
                        XMLDoc.MoveToContent();
                    }
                }
            }
        }
        /// <summary>
        /// Constructor instantiates a properly behaving UPnP-AV
        /// MediaServer device that has a root container.
        /// </summary>
        /// <param name="info">general information about the MediaServer like manufacturer info</param>
        /// <param name="isRootDevice">true if the MediaServer has no parent UPnP device</param>
        /// <param name="enableHttpContentServing">
        /// True, if the MediaServer should support the <see cref="MediaResource.AUTOMAPFILE"/>
        /// convention.
        /// </param>
        /// <param name="initialSourceProtocolInfoSet">
        /// Comma separated value list of protocolInfo strings for this MediaServer as a source.
        /// "HTTP-GET:*:*:*" is also allowed, indicating that any HTTP-GET resource is supported on the server.
        /// Generally, this value should be true unless the application logic for the
        /// MediaServer will always create resource objects with fully pathed URIs that are
        /// accessible from the UPNP network.
        /// </param>
        /// <param name="initialSinkProtocolInfoSet">
        /// Comma separated value list of protocolInfo strings for this MediaServer as a sink.
        /// This should generally be blank although it may be possible to eventually 
        /// migrate this implementation to behave both as a MediaRenderer and a MediaServer,
        /// although there may be subtleties that make such a device impossible.
        /// </param>
        public MediaServerDevice(
			DeviceInfo info,
			UPnPDevice parent,
			bool enableHttpContentServing,
			string initialSourceProtocolInfoSet,
			string initialSinkProtocolInfoSet
			)
        {
            // enable HTTP webserving of HTTP-GET resource/content?
            this.EnableHttp = enableHttpContentServing;

            // Wire up the delegate and weak event used when an HTTP transfer should be
            // removed from the server's list.
            // When an HTTP transfer completes it's progress info still needs to be
            // available for GetTransferProgress action for at least 30 seconds.
            // LifeTimeMonitor will delay the removal for such a time, and then
            // execute the delegate.
            this.LTMDelegate = new LifeTimeMonitor.LifeTimeHandler(this.Sink_OnExpired);
            this.m_LFT.OnExpired += LTMDelegate;

            // Create the UPnP device object - no servics are attached yet
            if (parent == null)
            {
                this.Device = UPnPDevice.CreateRootDevice(info.CacheTime, 1.0, info.LocalRootDirectory);
                if(info.CustomUDN!="")
                {
                    this.Device.UniqueDeviceName = info.CustomUDN;
                }
            }
            else
            {
                Guid udn = System.Guid.NewGuid();
                this.Device = UPnPDevice.CreateEmbeddedDevice(1.0, udn.ToString());
                parent.AddDevice(this.Device);
            }

            // transfer basic info about the device, like serial #, manufacturer, etc.
            this.Device.HasPresentation = false;
            this.Device.StandardDeviceType = "MediaServer";

            this.Device.FriendlyName		= info.FriendlyName;
            this.Device.Manufacturer		= info.Manufacturer;
            this.Device.ManufacturerURL	= info.ManufacturerURL;
            this.Device.ModelName			= info.ModelName;
            this.Device.ModelDescription	= info.ModelDescription;
            if (info.ModelURL != null)
            {
                try
                {
                    this.Device.ModelURL			= new Uri(info.ModelURL);
                }
                catch
                {
                    this.Device.ModelURL = null;
                }
            }
            this.Device.ModelNumber		= info.ModelNumber;

            if (info.INMPR03)
            {
                this.Device.AddCustomFieldInDescription("INMPR03", "1.0", "");
            }

            this.ConnectionManager = new DvConnectionManager();
            this.ContentDirectory = new DvContentDirectory();

            // Set periodic behavior for the moderated state variables.
            // Only state variables that do not overwrite a pending
            // value need an accumulator.
            //
            this.ContentDirectory.ModerationDuration_SystemUpdateID = 2;
            this.ContentDirectory.ModerationDuration_ContainerUpdateIDs = 2;
            this.ContentDirectory.Accumulator_ContainerUpdateIDs = new Accumulator_ContainerUpdateIDs();

            // Determine whether the application logic actually
            // wants control points to have access to content management
            // related methods. If not, then remove those actions.
            if (info.AllowRemoteContentManagement==false)
            {
                this.ContentDirectory.RemoveAction_CreateObject();
                this.ContentDirectory.RemoveAction_CreateReference();
                this.ContentDirectory.RemoveAction_DeleteResource();
                this.ContentDirectory.RemoveAction_DestroyObject();
                this.ContentDirectory.RemoveAction_ImportResource();
                this.ContentDirectory.RemoveAction_UpdateObject();
                this.ContentDirectory.RemoveAction_ExportResource();
                this.ContentDirectory.RemoveAction_GetTransferProgress();
                this.ContentDirectory.RemoveAction_StopTransferResource();
            }

            if (info.EnablePrepareForConnection==false)
            {
                this.ConnectionManager.RemoveAction_PrepareForConnection();
            }

            if (info.EnableConnectionComplete==false)
            {
                this.ConnectionManager.RemoveAction_ConnectionComplete();
            }

            if (
                (info.EnablePrepareForConnection==false) &&
                (info.EnableConnectionComplete==false)
                )
            {
                ProtocolInfoString protInfo = new ProtocolInfoString("http-get:*:*:*");
                DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus status = DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus.UNKNOWN;

                Connection newConnection = new Connection(GetConnectionID(), -1, -1, -1, protInfo, "/", OpenSource.UPnP.AV.DvConnectionManager.Enum_A_ARG_TYPE_Direction.OUTPUT, OpenSource.UPnP.AV.DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus.UNKNOWN);
                this.AddConnection(newConnection);
            }

            if (info.EnableSearch == false)
            {
                this.ContentDirectory.RemoveAction_Search();
            }

            this.m_SearchCapabilities = info.SearchCapabilities;
            this.m_SortCapabilities = info.SortCapabilities;

            //AVTransport and RendererControl not used...yet.
            //this.m_AVTransports = new ArrayList();
            //this.m_RenderingControls = new ArrayList();

            // Set values for each state variable
            //
            if (this.ConnectionManager.Evented_CurrentConnectionIDs == null)
            {
                this.ConnectionManager.Evented_CurrentConnectionIDs = "";
            }

            // this state variable does not exist until UPNP-AV 1.1
            //this.ConnectionManager.Evented_PhysicalConnections = "";

            // have the device advertise the protocolInfo strings for
            // this media server
            this.UpdateProtocolInfoSet(false, initialSinkProtocolInfoSet);
            this.UpdateProtocolInfoSet(true, initialSourceProtocolInfoSet);

            // initialize state varaibles
            this.ContentDirectory.Evented_ContainerUpdateIDs = "";
            this.ContentDirectory.Evented_SystemUpdateID = 0;
            this.ContentDirectory.Evented_TransferIDs = "";

            // Wire up the ContentDirectory and ConnectionManager actions to actual methods
            // in this class that will actually do the work.
            this.ConnectionManager.External_ConnectionComplete			= new DvConnectionManager.Delegate_ConnectionComplete(this.SinkCm_ConnectionComplete);
            this.ConnectionManager.External_GetCurrentConnectionIDs		= new DvConnectionManager.Delegate_GetCurrentConnectionIDs(this.SinkCm_GetCurrentConnectionIDs);
            this.ConnectionManager.External_GetCurrentConnectionInfo	= new DvConnectionManager.Delegate_GetCurrentConnectionInfo(this.SinkCm_GetCurrentConnectionInfo);
            this.ConnectionManager.External_GetProtocolInfo				= new DvConnectionManager.Delegate_GetProtocolInfo(this.SinkCm_GetProtocolInfo);
            this.ConnectionManager.External_PrepareForConnection		= new DvConnectionManager.Delegate_PrepareForConnection(this.SinkCm_PrepareForConnection);

            this.ContentDirectory.External_Browse					= new DvContentDirectory.Delegate_Browse(this.SinkCd_Browse);
            this.ContentDirectory.External_CreateObject				= new DvContentDirectory.Delegate_CreateObject(this.SinkCd_CreateObject);
            this.ContentDirectory.External_CreateReference			= new DvContentDirectory.Delegate_CreateReference(this.SinkCd_CreateReference);
            this.ContentDirectory.External_DeleteResource			= new DvContentDirectory.Delegate_DeleteResource(this.SinkCd_DeleteResource);
            this.ContentDirectory.External_DestroyObject			= new DvContentDirectory.Delegate_DestroyObject(this.SinkCd_DestroyObject);
            this.ContentDirectory.External_ExportResource			= new DvContentDirectory.Delegate_ExportResource(this.SinkCd_ExportResource);
            this.ContentDirectory.External_GetSearchCapabilities	= new DvContentDirectory.Delegate_GetSearchCapabilities(this.SinkCd_GetSearchCapabilities);
            this.ContentDirectory.External_GetSortCapabilities		= new DvContentDirectory.Delegate_GetSortCapabilities(this.SinkCd_GetSortCapabilities);
            this.ContentDirectory.External_GetSystemUpdateID		= new DvContentDirectory.Delegate_GetSystemUpdateID(this.SinkCd_GetSystemUpdateID);
            this.ContentDirectory.External_GetTransferProgress		= new DvContentDirectory.Delegate_GetTransferProgress(this.SinkCd_GetTransferProgress);
            this.ContentDirectory.External_ImportResource			= new DvContentDirectory.Delegate_ImportResource(this.SinkCd_ImportResource);
            this.ContentDirectory.External_Search					= new DvContentDirectory.Delegate_Search(this.SinkCd_Search);
            this.ContentDirectory.External_StopTransferResource		= new DvContentDirectory.Delegate_StopTransferResource(this.SinkCd_StopTransferResource);
            this.ContentDirectory.External_UpdateObject				= new DvContentDirectory.Delegate_UpdateObject(this.SinkCd_UpdateObject);

            // add the services to the device - voila, it's now a useful device
            this.Device.AddService(this.ConnectionManager);
            this.Device.AddService(this.ContentDirectory);

            // set up a virtual directory for local webserving - we'll always
            // have this here, even if HTTP webserving is not enabled because
            // it really doesn't hurt to have the virtual directory.
            Interlocked.Increment(ref VirtualDirCounter);
            m_VirtualDirName = "MediaServerContent_" + VirtualDirCounter.ToString();
            this.Device.AddVirtualDirectory(m_VirtualDirName, new UPnPDevice.VirtualDirectoryHandler(this.WebServer_OnHeaderReceiveSink), new UPnPDevice.VirtualDirectoryHandler(this.WebServer_OnPacketReceiveSink));

            // create the root container for this media server's content hierarchy.
            // Prevent control points from modifying this root container or
            // creating new objects in the root.
            // Also need to wire up internally visible events so that the MediaServer
            // will properly event changes in the content hierarchy.
            MediaBuilder.container rootInfo = new MediaBuilder.container("Root");
            rootInfo.Searchable = true;
            rootInfo.IsRestricted = true;
            this.m_Root = (DvRootContainer) DvMediaBuilder.CreateRoot(rootInfo);
            this.m_Root.OnContainerChanged += new DvRootContainer.Delegate_OnContainerChanged(this.Sink_ContainerChanged);

            // At this point the device is ready to go... simply call the Start()
            // method to have the device advertise itself.
        }
        private UPnPDevice BuildDevice(TreeNode node, UPnPDevice parentDevice)
        {
            if (node.Tag == null || node.Tag.GetType() != typeof(UPnPDevice)) return null;

            UPnPDevice device = (UPnPDevice)node.Tag;
            UPnPDevice dev;

            if (parentDevice == null)
            {
                dev = UPnPDevice.CreateRootDevice(600, 1.0, "");
                dev.SerialNumber = "0000001";
                dev.User = device.User;
                dev.Icon = ((ServiceGenerator.Configuration)device.User).IconImageSM;
                dev.Icon2 = ((ServiceGenerator.Configuration)device.User).IconImageLG;
            }
            else
            {
                dev = UPnPDevice.CreateEmbeddedDevice(1.0, System.Guid.NewGuid().ToString());
                dev.User = device.User;
            }

            dev.FriendlyName = device.FriendlyName;
            dev.DeviceURN = device.DeviceURN;
            dev.Manufacturer = device.Manufacturer;
            dev.ManufacturerURL = device.ManufacturerURL;
            dev.ModelDescription = device.ModelDescription;
            dev.ModelName = device.ModelName;
            dev.ModelNumber = device.ModelNumber;
            dev.ProductCode = device.ProductCode;
            dev.SerialNumber = device.SerialNumber;

            foreach (TreeNode n in node.Nodes)
            {
                if (n.Tag != null && n.Tag.GetType() == typeof(UPnPService))
                {
                    dev.AddService((UPnPService)n.Tag);
                }
            }

            foreach (TreeNode n in node.Nodes)
            {
                if (n.Tag != null && n.Tag.GetType() == typeof(UPnPDevice))
                {
                    BuildDevice(n, dev);
                }
            }

            if (parentDevice != null) parentDevice.AddDevice(dev);

            return dev;
        }
        /// <summary>
        /// Parses the embedded devices from a device xml
        /// </summary>
        /// <param name="XML">The xml document to parse the devices from</param>
        /// <param name="RetVal">The owning-UPnP device to which the parsed devices will be added as embedded devices</param>
        private static void ParseDeviceList(String XML, ref UPnPDevice RetVal)
        {
            StringReader MyString = new StringReader(XML);
            XmlTextReader XMLDoc = new XmlTextReader(MyString);
            UPnPDevice EmbeddedDevice = null;

            XMLDoc.Read();
            XMLDoc.MoveToContent();

            if (XMLDoc.LocalName == "deviceList")
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                while (XMLDoc.LocalName != "deviceList" && !XMLDoc.EOF)
                {
                    if (XMLDoc.LocalName == "device")
                    {
                        EmbeddedDevice = new UPnPDevice();
                        EmbeddedDevice.IsRoot = false;
                        EmbeddedDevice.BaseURL = RetVal.BaseURL;
                        string devicexml = "Failed to read the xml element for the embedded Device from the parent Device XML";
                        // TODO: DONE Resilience case 6 - wrap in try-catch
                        try
                        {
                            devicexml = "<device>\r\n" + XMLDoc.ReadInnerXml() + "</device>";
                            ParseDevice(devicexml, ref EmbeddedDevice);
                            // TODO: DONE Resilience case 6 - only add if it is not null
                            if (EmbeddedDevice != null)
                            {
                                RetVal.AddDevice(EmbeddedDevice);
                            }
                        }
                        catch (Exception e)
                        {
                            OpenSource.Utilities.EventLogger.Log(null, System.Diagnostics.EventLogEntryType.Error, "Invalid EmbeddedDevice XML");
                            OpenSource.Utilities.EventLogger.Log(e, "XML content: \r\n" + devicexml);
                            OpenSource.Utilities.EventLogger.Log(null, System.Diagnostics.EventLogEntryType.Warning, "Dropping failed Embedded Device and commencing parsing remainder of device");
                        }
                    }
                    if (!XMLDoc.IsStartElement() && XMLDoc.LocalName != "deviceList")
                    {
                        XMLDoc.Read();
                        XMLDoc.MoveToContent();
                    }
                }
            }
        }