/// <summary> /// Returns true if the supplied ProtocolInfoString is an acceptable match. /// The supplied ProtocolInfoString's mime-type and info fields must represent a superset or the /// same set as this instance. Basically, the algorithm works like this. /// <list type="number"> /// <item><description>If the protocols match..</description></item> /// <item><description>...and the networks match</description></item> /// <item><description>...and (if the mime types match) OR (if the argument protocolInfo mime type is *)</description></item> /// <item><description>...and (if the info fields match) OR (if the argument protocolInfo info field is *)</description></item> /// <item><description>Then we return true.</description></item> /// </list> /// </summary> /// <param name="protocolInfo">supplied protocolInfo string; the * symbol can be applied to indicate any value</param> /// <returns>True indicates that the supplied protocolInfo is the same or a superset.</returns> public bool Matches(ProtocolInfoString protocolInfo) { if (protocolInfo.Protocol == this.Protocol) { if (protocolInfo.Network == this.Network) { if ((protocolInfo.MimeType == "*") || (protocolInfo.MimeType == this.MimeType)) { if ((protocolInfo.Info == "*") || (protocolInfo.Info == this.Info)) { return(true); } } } } return(false); }
private IDvMedia CreateObjFromFile(FileInfo file, ArrayList childPlaylists) { IDvMedia retVal = null; string ext = file.Extension.ToUpper(); string mime = null, mclass = null; switch (ext) { case ".ASF": case ".AVI": case ".WMV": case ".MPEG": case ".MPEG2": case ".MPG": retVal = CreateItemFromGenericVideoFile(file); break; case ".WAV": case ".WMA": case ".MP3": DvMediaItem item = CreateItemFromMp3WmaFile(file); if (item == null) { item = this.CreateAudioItemFromFormatedNameFile(file); } retVal = item; break; case ".M3U": retVal = this.CreateM3uPlaylistContainer(file, childPlaylists); break; case ".ASX": break; case ".GIF": case ".JPG": case ".BMP": case ".TIF": case ".PNG": retVal = CreateItemFromImageFile(file); break; case ".CDSLNK": retVal = CreateItemFromCdsLink(file); break; default: retVal = CreateItemFromGenericFile(file); break; } if (retVal != null) { MimeTypes.ExtensionToMimeType(ext, out mime, out mclass); } if (mime != null) { if (this.m_MimeTypes.Contains(mime) == false) { this.m_MimeTypes.Add(mime); ProtocolInfoString[] ps = new ProtocolInfoString[this.m_MimeTypes.Count]; for (int i=0; i < this.m_MimeTypes.Count; i++) { ps[i] = new ProtocolInfoString("http-get:*:"+this.m_MimeTypes[i].ToString()+":*"); } this.mediaServer.SourceProtocolInfoSet = ps; } } return retVal; }
/// <summary> /// Returns true if the supplied ProtocolInfoString is an acceptable match. /// The supplied ProtocolInfoString's mime-type and info fields must represent a superset or the /// same set as this instance. Basically, the algorithm works like this. /// <list type="number"> /// <item><description>If the protocols match..</description></item> /// <item><description>...and the networks match</description></item> /// <item><description>...and (if the mime types match) OR (if the argument protocolInfo mime type is *)</description></item> /// <item><description>...and (if the info fields match) OR (if the argument protocolInfo info field is *)</description></item> /// <item><description>Then we return true.</description></item> /// </list> /// </summary> /// <param name="protocolInfo">supplied protocolInfo string; the * symbol can be applied to indicate any value</param> /// <returns>True indicates that the supplied protocolInfo is the same or a superset.</returns> public bool Matches (ProtocolInfoString protocolInfo) { if (protocolInfo.Protocol == this.Protocol) { if (protocolInfo.Network == this.Network) { if ((protocolInfo.MimeType == "*") || (protocolInfo.MimeType == this.MimeType)) { if ((protocolInfo.Info == "*") || (protocolInfo.Info == this.Info)) { return true; } } } } return false; }
/// <summary> /// This is used to determine if the renderer supports a given protocol type. /// </summary> /// <param name="ProtocolInfo">The ProtocolInfo you wish to check</param> /// <returns>true if supported</returns> public bool SupportsProtocolInfo(ProtocolInfoString ProtocolInfo) { bool RetVal = false; foreach(ProtocolInfoString pis in ProtocolInfoList) { if(pis.Matches(ProtocolInfo)) { RetVal = true; break; } } return(RetVal); }
/// <summary> /// Returns the current values of a protocolInfo set. /// </summary> /// <param name="sourceProtocolInfo">true, if the source protocolInfo set is desired</param> /// <returns>array of protocolInfo strings</returns> private ProtocolInfoString[] GetProtocolInfoSet(bool sourceProtocolInfo) { ArrayList arrayList; ReaderWriterLock ReaderWriterLock; if (sourceProtocolInfo) { arrayList = this.m_SourceProtocolInfoSet; ReaderWriterLock = this.m_LockSourceProtocolInfo; } else { arrayList = this.m_SinkProtocolInfoSet; ReaderWriterLock = this.m_LockSinkProtocolInfo; } // Obtaining a list of protocol info strings. // ReaderWriterLock.AcquireReaderLock(-1); ProtocolInfoString[] array = new ProtocolInfoString[ arrayList.Count ]; for (int i=0; i < arrayList.Count; i++) { array[i] = (ProtocolInfoString) arrayList[i]; } ReaderWriterLock.ReleaseReaderLock(); return array; }
public void OnDeserialization(object sender) { this.m_ProtocolInfo = new ProtocolInfoString( this.m_ProtocolInfo.ToString() ); }
/// <summary> /// Allows construction of a media resource from an XmlElement /// that represents the "res" node, and is also DIDL-Lite compliant. /// </summary> /// <param name="xmlElement"></param> public MediaResource(XmlElement xmlElement) { OpenSource.Utilities.InstanceTracker.Add(this); bool foundProtInfo = false; lock (this.m_Attributes.SyncRoot) { foreach (XmlAttribute attrib in xmlElement.Attributes) { if (String.Compare(attrib.LocalName, T[_ATTRIB.protocolInfo], true) == 0) { this.m_ProtocolInfo = new ProtocolInfoString(attrib.Value); foundProtInfo = true; } else if (String.Compare(attrib.LocalName, T[_ATTRIB.importUri], true) == 0) { if (attrib.Value.ToString() != "") { _Hashtable.Set(m_Attributes, T[_ATTRIB.importUri], attrib.Value); } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.bitrate], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.bitrate], new _UInt(uint.Parse(attrib.Value))); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.bitsPerSample], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.bitsPerSample], new _UInt(uint.Parse(attrib.Value))); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.colorDepth], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.colorDepth], new _UInt(uint.Parse(attrib.Value))); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.duration], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.duration], new _TimeSpan(attrib.Value)); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.nrAudioChannels], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.nrAudioChannels], new _UInt(uint.Parse(attrib.Value))); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.protection], true) == 0) { try { if (attrib.Value.ToString() != "") { _Hashtable.Set(m_Attributes, T[_ATTRIB.protection], attrib.Value); } } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.resolution], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.resolution], new ImageDimensions(attrib.Value)); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.sampleFrequency], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.sampleFrequency], new _UInt(uint.Parse(attrib.Value))); } catch { } } else if (String.Compare(attrib.LocalName, T[_ATTRIB.size], true) == 0) { try { _Hashtable.Set(m_Attributes, T[_ATTRIB.size], new _ULong(ulong.Parse(attrib.Value))); } catch { } } } if (foundProtInfo == false) { this.m_ProtocolInfo = new ProtocolInfoString(ProtocolInfoString.DefaultValue); } } m_ContentUri = xmlElement.InnerText.Trim(); }
public AVRenderer(int MaxConnections, ProtocolInfoString[] Info) : this(MaxConnections,Info,null) { }
/// <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. }
/// <summary> /// Method ensures that the protocolInfo for a PrepareForConnection request /// matches up correctly with a supported protocol on the device. /// The check is a trivial check and nothing more. /// <see cref="MediaServerDevice.SinkCm_PrepareForConnection"/> /// will do additional checks to ensure that the entire request is correct. /// </summary> /// <param name="protInfo">protocolInfo string proposed in the request</param> /// <param name="dir">direction of the stream, relative to the server</param> private void ValidateConnectionRequest(ProtocolInfoString protInfo, DvConnectionManager.Enum_A_ARG_TYPE_Direction dir) { bool incompatibleProtocol = true; // Grab the correct protocolInfo set, depending on whether // the stream is supposed to be a source or a sink. ArrayList al; if (dir == DvConnectionManager.Enum_A_ARG_TYPE_Direction.INPUT) { al = this.m_SinkProtocolInfoSet; } else if (dir == DvConnectionManager.Enum_A_ARG_TYPE_Direction.OUTPUT) { al = this.m_SourceProtocolInfoSet; } else { throw new Error_InvalidDirection(""); } // Compare the requested protocol info string against the // list of available ones. // foreach (ProtocolInfoString prot in al) { if (protInfo.Matches(prot)) { incompatibleProtocol = false; break; } } if (incompatibleProtocol) { throw new Error_IncompatibleProtocolInfo("("+protInfo.ToString()+")"); } }
/// <summary> /// Constructor - requires all of the information before the connection is created. /// </summary> /// <param name="id"></param> /// <param name="peerId"></param> /// <param name="rcs"></param> /// <param name="avt"></param> /// <param name="prot"></param> /// <param name="peer"></param> /// <param name="dir"></param> /// <param name="status"></param> /// <exception cref="ApplicationException"> /// Thrown if the proposed connection ID is less than zero. /// </exception> public Connection(int id, int peerId, int rcs, int avt, ProtocolInfoString prot, string peer, DvConnectionManager.Enum_A_ARG_TYPE_Direction dir, DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus status) { if (id < 0) { throw new ApplicationException("ConnectionId cannot be negative."); } ConnectionId = id; PeerConnectionId = peerId; RcsId = rcs; AVTransportId = avt; ProtocolInfo = prot; PeerConnectionManager = peer; Direction = dir; Status = status; }
/// <summary> /// Method used by UpdateProtocolInfoSet(bool, string) to /// actually change the protocolInfo strings. /// This method will also cause the server to event the changes /// in the state variable. /// </summary> /// <param name="sourceProtocolInfo">true if the source protocolInfo set is to be changed</param> /// <param name="array">new list of protocolInfo strings for the set</param> private void UpdateProtocolInfoSet(bool sourceProtocolInfo, ProtocolInfoString[] array) { ArrayList arrayList; ReaderWriterLock ReaderWriterLock; if (sourceProtocolInfo) { arrayList = this.m_SourceProtocolInfoSet; ReaderWriterLock = this.m_LockSourceProtocolInfo; } else { arrayList = this.m_SinkProtocolInfoSet; ReaderWriterLock = this.m_LockSinkProtocolInfo; } // Updating the list of protocol info strings. // ReaderWriterLock.AcquireWriterLock(-1); StringBuilder sb = new StringBuilder(); if (array != null) { arrayList.Clear(); arrayList.AddRange(array); for (int i=0; i < arrayList.Count; i++) { if (i > 0) sb.Append(","); sb.Append(array[i].ToString()); } } if (sourceProtocolInfo) { this.ConnectionManager.Evented_SourceProtocolInfo = sb.ToString(); } else { this.ConnectionManager.Evented_SinkProtocolInfo = sb.ToString(); } ReaderWriterLock.ReleaseWriterLock(); }
/// <summary> /// This method changes the source or sink protocolInfo sets /// for the media server. /// </summary> /// <param name="sourceProtocolInfo">true, if changing source protocolInfo set</param> /// <param name="protocolInfoSet">new protocolInfo strings, separated by commas</param> private void UpdateProtocolInfoSet(bool sourceProtocolInfo, string protocolInfoSet) { DText parser = new DText(); parser.ATTRMARK = ","; parser[0] = protocolInfoSet; int cnt = parser.DCOUNT(); ArrayList prots = new ArrayList(); for (int i=1; i <= cnt; i++) { string val = parser[i].Trim(); if (val != "") { ProtocolInfoString protInfo = new ProtocolInfoString("*:*:*:*"); bool error = false; try { protInfo = new ProtocolInfoString(val); } catch { error = true; } if (error == false) { prots.Add(protInfo); } } } ProtocolInfoString[] protArray = null; if (prots.Count > 0) { protArray = (ProtocolInfoString[]) prots.ToArray(prots[0].GetType()); } this.UpdateProtocolInfoSet(sourceProtocolInfo, protArray); }
/// <summary> /// Method executes when a control point invokes the ConnectionManager.PrepareForConnection action. /// The method will attempt to validate the connection request, reporting an error if /// the connection type is not supported. If the connection type is supported, but /// it is not based on HTTP-GET we execute the <see cref="MediaServerDevice.OnCallPrepareForConnection"/> /// delegate and ask upper-layer software to accept or reject the request. /// If the upper-layer is to reject, then it must throw a UPnPCustomException() that provides /// a reason for the failure. /// </summary> /// <param name="RemoteProtocolInfo">The protocolInfo string that identifies transport/network/mime-type/info for the proposed connection.</param> /// <param name="PeerConnectionManager">The UDN/Service-ID of the ConnectionManager service at the other end of the connection.</param> /// <param name="PeerConnectionID">The connection ID returned by the PrepareForConnection invocation on the other endpoint. Can be empty if unknown.</param> /// <param name="Direction">Should generally by OUTPUT.</param> /// <param name="ConnectionID">Returns ConnectionID used by this mediaserver to represent the new connection.</param> /// <param name="AVTransportID"> /// Returns AVTransport instance ID used by this mediaserver to represent the new connection. /// Value is -1 for HTTP-GET content on a server. /// </param> /// <param name="RcsID"> /// Returns RendererControl instance ID used by this mediaserver to represent the new connection. /// Value is -1 for HTTP-GET content on a server. /// </param> private void SinkCm_PrepareForConnection(System.String RemoteProtocolInfo, System.String PeerConnectionManager, System.Int32 PeerConnectionID, DvConnectionManager.Enum_A_ARG_TYPE_Direction Direction, out System.Int32 ConnectionID, out System.Int32 AVTransportID, out System.Int32 RcsID) { bool ownerProvidesIdInfo = true; ProtocolInfoString protInfo = new ProtocolInfoString(RemoteProtocolInfo); // Throw an exception if the protocol and direction are not supported by this device. // ValidateConnectionRequest(protInfo, Direction); // If the instance is configured to serve local HTTP content, // then we intercept any PrepareForConnection() invocation // that involves HTTP-GET / OUTPUT and create a new ConnectionID, // and provide -1 for AVT and RCS instance IDs. // // In all other cases, we fire an event asking the owner to // provide this information. // if ((this.EnableHttp) && (String.Compare(protInfo.Protocol, "http-get", true) == 0) && (Direction == DvConnectionManager.Enum_A_ARG_TYPE_Direction.OUTPUT)) { ownerProvidesIdInfo = false; } // Obtain a valid connection ID regardless of whether the owner will provide // an AVTransportID and/or a RcsID. // ConnectionID = GetConnectionID(); DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus status = DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus.UNKNOWN; if (ownerProvidesIdInfo) { if (this.OnCallPrepareForConnection != null) { // Application logic needs to provide a instance IDs for AVTransport and Rendering Control services, as well as // an initial value for the status. this.OnCallPrepareForConnection(RemoteProtocolInfo, PeerConnectionManager, Direction, out AVTransportID, out RcsID, out status); } else { throw new Error_InvalidServerConfiguration("PrepareForConnection() cannot be supported until the vendor configures the server correctly."); } } else { AVTransportID = -1; RcsID = -1; } Connection newConnection = new Connection((int)ConnectionID, PeerConnectionID, RcsID, AVTransportID, protInfo, PeerConnectionManager, Direction, status); this.AddConnection(newConnection); this.m_Stats.PrepareForConnection++; this.FireStatsChange(); }
private void ValidateBranch(DvMediaContainer branchFrom, IDvMedia branch, bool allowNewLocalResources) { DvMediaContainer parent = branchFrom; string basePath = ""; if (allowNewLocalResources) { /// The parent container's TAG field will have one of two things: /// 1) string representation of the local path that it maps to.. /// 2) InnerMediaDirectory structure describing the local path that it maps to. /// 3) Empty string value or null if no mapping to a local file. /// if (parent.Tag == null) { } else if (parent.Tag.GetType() == new InnerMediaDirectory().GetType()) { InnerMediaDirectory imd = (InnerMediaDirectory) parent.Tag; basePath = imd.directory.FullName + "\\"; } else if (parent.Tag.GetType() == typeof(string)) { basePath = parent.Tag + "\\"; } /// The new branch must be a storage container in order to /// map to a local file of sort. May consider making /// the class more restricted to object.container.storageFolder. /// if (branch.IsContainer) { DvMediaContainer container = (DvMediaContainer) branch; if (container.Class.ToString().StartsWith("object.container.storage")) //if (true) { container.Tag = basePath + container.Title; } else { container.Tag = null; } } } if (branch.IsContainer) { DvMediaContainer container = (DvMediaContainer) branch; foreach (IDvMedia child in container.CompleteList) { ValidateBranch(container, child, allowNewLocalResources); } } else if (branch.IsItem) { } else { throw new Exception("Error: Could not validate branch. Branch must be a container, reference, or item."); } if (branch.IsReference == false) { /// Each of these resources should be actual children of the item. /// They should not be resources obtained through a reference. /// This impelementation does not allow references to declare /// their own resources. /// IList resources = branch.Resources; if (resources != null) { if (resources.Count > 0) { foreach (DvMediaResource res in resources) { if (res.ContentUri.StartsWith(DvMediaResource.AUTOMAPFILE)) { if (allowNewLocalResources) { string filePath = res.ContentUri.Substring(DvMediaResource.AUTOMAPFILE.Length); if (File.Exists(filePath)) { if (Directory.Exists(filePath)) { throw new UPnPCustomException(810, "The specified local file-uri is a directory. (" +res.ContentUri+")"); } FileInfo fi = new FileInfo(filePath); string protocol = "http-get"; string network = "*"; string mime; string classType; MimeTypes.ExtensionToMimeType(fi.Extension, out mime, out classType); string info = "*"; StringBuilder sb = new StringBuilder(100); sb.AppendFormat("{0}:{1}:{2}:{3}", protocol, network, mime, info); ProtocolInfoString protInfo = new ProtocolInfoString(sb.ToString()); res.SetProtocolInfo(protInfo); } else { throw new UPnPCustomException(811, "The specified local file-uri does not exist. (" +res.ContentUri+")"); } } else { throw new Error_BadMetadata("Cannot create local http-get resources that are descendents from the specified container."); } } else if ((res.ContentUri == "") && (basePath != "")) { // Get a unique filename where we can save the binary when it gets imported // or sent. string filePath = res.GenerateLocalFilePath(basePath); /// Set the content uri to map to the determined local path... /// although it's understood that the file does not exist yet. /// res.SetContentUri(filePath); } else if (res.ContentUri != "") { string importUri = res.ImportUri; //int x = 3; } else { throw new Error_RestrictedObject("The container specified does not allow creation of storage containers or resources."); } } } } } }
/// <summary> /// Returns true if the provided ProtocolInfoString /// object is equivalent to this object. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { ProtocolInfoString protInfo = (ProtocolInfoString)obj; return(protInfo._value == this._value); }
public AVConnection(AVRenderer _parent, System.String RemoteProtocolInfo, System.String PeerConnectionManager, int PeerConnectionID, DvConnectionManager.Enum_A_ARG_TYPE_Direction Direction, System.Int32 ConnectionID, System.Int32 AVTransportID, System.Int32 RcsID) { Parent = _parent; foreach(string V in DvRenderingControl.Values_A_ARG_TYPE_Channel) { MuteChannelTable[V] = false; VolumeChannelTable[V] = (UInt16)0; } _InfoString = new ProtocolInfoString(RemoteProtocolInfo); _PeerManager = PeerConnectionManager; _PeerManagerID = PeerConnectionID; Connection_ID = ConnectionID; AVTransport_ID = AVTransportID; RenderingControl_ID = RcsID; _Direction = Direction; }
/// <summary> /// Indicates vendor specific UPNP error code of 876. /// </summary> /// <param name="contentUri">The contentUri value of the MediaResource when the protocolInfo modification was attempted.</param> /// <param name="protocolInfo">The value of the intended protocolInfo string.</param> public Error_CannotSetProtocolInfo(string contentUri, ProtocolInfoString protocolInfo) : base(876, "Cannot set the protocolInfo string (" +protocolInfo.ToString()+ ") to something other than \"http-get\", if the contentUri value starts with (" +MediaResource.AUTOMAPFILE+").") { this.ContentUri = contentUri; this.ProtocolInfo = protocolInfo; }
public AVRenderer(int MaxConnections, ProtocolInfoString[] Info, ConnectionHandler h) { ConnectionMax = MaxConnections; OnNewConnection += h; InfoStrings = Info; device = UPnPDevice.CreateEmbeddedDevice(1,Guid.NewGuid().ToString()); device.FriendlyName = "AVRenderer Device (" + Dns.GetHostName() +")"; AVT = new DvAVTransport(); AVT.GetUPnPService().Major = 1; AVT.GetUPnPService().Minor = 0; Manager = new DvConnectionManager(); Manager.GetUPnPService().Major = 1; Manager.GetUPnPService().Minor = 0; Control = new DvRenderingControl(); Control.GetUPnPService().Major = 1; Control.GetUPnPService().Minor = 0; Manager.External_PrepareForConnection = new DvConnectionManager.Delegate_PrepareForConnection(PrepareForConnectionSink); Manager.External_ConnectionComplete = new DvConnectionManager.Delegate_ConnectionComplete(ConnectionCompleteSink); Manager.External_GetCurrentConnectionIDs = new DvConnectionManager.Delegate_GetCurrentConnectionIDs(GetCurrentConnectionIDsSink); Manager.External_GetProtocolInfo = new DvConnectionManager.Delegate_GetProtocolInfo(GetProtocolInfoSink); Manager.External_GetCurrentConnectionInfo = new DvConnectionManager.Delegate_GetCurrentConnectionInfo(GetCurrentConnectionInfoSink); Manager.Evented_CurrentConnectionIDs = ""; //Manager.Evented_PhysicalConnections = ""; string Sink = ""; foreach(ProtocolInfoString s in InfoStrings) { if(Sink=="") { Sink = s.ToString(); } else { Sink = Sink + "," + s.ToString(); } } Manager.Evented_SinkProtocolInfo = Sink; Manager.Evented_SourceProtocolInfo = ""; AVT.Accumulator_LastChange = new InstanceID_LastChangeAccumulator("AVT"); AVT.ModerationDuration_LastChange = 0.5; AVT.Evented_LastChange = "<Event xmlns = "urn:schemas-upnp-org:metadata-1-0/AVT/"/>"; AVT.External_GetMediaInfo = new DvAVTransport.Delegate_GetMediaInfo(GetMediaInfoSink); AVT.External_GetPositionInfo = new DvAVTransport.Delegate_GetPositionInfo(GetPositionInfoSink); AVT.External_GetTransportInfo = new DvAVTransport.Delegate_GetTransportInfo(GetTransportInfoSink); AVT.External_GetTransportSettings = new DvAVTransport.Delegate_GetTransportSettings(GetTransportSettingsSink); AVT.External_GetDeviceCapabilities = new DvAVTransport.Delegate_GetDeviceCapabilities(GetDeviceCapabilitiesSink); AVT.External_GetCurrentTransportActions = new DvAVTransport.Delegate_GetCurrentTransportActions(GetCurrentTransportActionsSink); AVT.External_Play = new DvAVTransport.Delegate_Play(PlaySink); AVT.External_Stop = new DvAVTransport.Delegate_Stop(StopSink); AVT.External_Pause = new DvAVTransport.Delegate_Pause(PauseSink); AVT.External_Record = new DvAVTransport.Delegate_Record(RecordSink); AVT.External_Previous = new DvAVTransport.Delegate_Previous(PreviousSink); AVT.External_Next = new DvAVTransport.Delegate_Next(NextSink); AVT.External_Seek = new DvAVTransport.Delegate_Seek(SeekSink); AVT.External_SetAVTransportURI = new DvAVTransport.Delegate_SetAVTransportURI(SetAVTransportURISink); AVT.External_SetNextAVTransportURI = new DvAVTransport.Delegate_SetNextAVTransportURI(SetNextAVTransportURISink); AVT.External_SetPlayMode = new DvAVTransport.Delegate_SetPlayMode(SetPlayModeSink); AVT.External_SetRecordQualityMode = new DvAVTransport.Delegate_SetRecordQualityMode(SetRecordQualityModeSink); AVT.External_Record = new DvAVTransport.Delegate_Record(RecordSink); Control.Evented_LastChange = "<Event xmlns = "urn:schemas-upnp-org:metadata-1-0/RCS/"/>"; Control.Accumulator_LastChange = new InstanceID_LastChangeAccumulator("RCS"); Control.ModerationDuration_LastChange = 1; Control.External_GetMute = new DvRenderingControl.Delegate_GetMute(GetMuteSink); Control.External_SetMute = new DvRenderingControl.Delegate_SetMute(SetMuteSink); Control.External_GetVolume = new DvRenderingControl.Delegate_GetVolume(GetVolumeSink); Control.External_SetVolume = new DvRenderingControl.Delegate_SetVolume(SetVolumeSink); Control.External_GetBlueVideoBlackLevel = new DvRenderingControl.Delegate_GetBlueVideoBlackLevel(GetBlueVideoBlackSink); Control.External_GetBlueVideoGain = new DvRenderingControl.Delegate_GetBlueVideoGain(GetBlueVideoGainSink); Control.External_SetBlueVideoBlackLevel = new DvRenderingControl.Delegate_SetBlueVideoBlackLevel(SetBlueVideoBlackSink); Control.External_SetBlueVideoGain = new DvRenderingControl.Delegate_SetBlueVideoGain(SetBlueVideoGainSink); Control.External_GetGreenVideoBlackLevel = new DvRenderingControl.Delegate_GetGreenVideoBlackLevel(GetGreenVideoBlackSink); Control.External_GetGreenVideoGain = new DvRenderingControl.Delegate_GetGreenVideoGain(GetGreenVideoGainSink); Control.External_SetGreenVideoBlackLevel = new DvRenderingControl.Delegate_SetGreenVideoBlackLevel(SetGreenVideoBlackSink); Control.External_SetGreenVideoGain = new DvRenderingControl.Delegate_SetGreenVideoGain(SetGreenVideoGainSink); Control.External_GetRedVideoBlackLevel = new DvRenderingControl.Delegate_GetRedVideoBlackLevel(GetRedVideoBlackSink); Control.External_GetRedVideoGain = new DvRenderingControl.Delegate_GetRedVideoGain(GetRedVideoGainSink); Control.External_SetRedVideoBlackLevel = new DvRenderingControl.Delegate_SetRedVideoBlackLevel(SetRedVideoBlackSink); Control.External_SetRedVideoGain = new DvRenderingControl.Delegate_SetRedVideoGain(SetRedVideoGainSink); Control.External_GetBrightness = new DvRenderingControl.Delegate_GetBrightness(GetBrightnessSink); Control.External_SetBrightness = new DvRenderingControl.Delegate_SetBrightness(SetBrightnessSink); Control.External_GetContrast = new DvRenderingControl.Delegate_GetContrast(GetContrastSink); Control.External_SetContrast = new DvRenderingControl.Delegate_SetContrast(SetContrastSink); Control.External_GetSharpness = new DvRenderingControl.Delegate_GetSharpness(GetSharpnessSink); Control.External_SetSharpness = new DvRenderingControl.Delegate_SetSharpness(SetSharpnessSink); Control.External_ListPresets = new DvRenderingControl.Delegate_ListPresets(ListPresetsSink); Control.External_SelectPreset = new DvRenderingControl.Delegate_SelectPreset(SelectPresetSink); device.Manufacturer = "OpenSource"; device.ManufacturerURL = ""; device.PresentationURL = "/"; device.HasPresentation = false; device.ModelName = "Renderer"; device.ModelDescription = "AV Media Renderer Device"; device.ModelURL = new Uri("http://www.sourceforge.org"); device.StandardDeviceType = "MediaRenderer"; device.AddService(Manager); device.AddService(Control); device.AddService(AVT); if(ConnectionMax == 0) { Manager.Evented_CurrentConnectionIDs = "0"; CurrentConnections = 1; AVConnection c = new AVConnection(this, "", "/", -1, DvConnectionManager.Enum_A_ARG_TYPE_Direction.INPUT, 0, 0, 0); c.Parent = this; c._WhoCreatedMe = new IPEndPoint(IPAddress.Parse("127.0.0.1"),0); ID_Table[(UInt32)0] = c; if(h!=null) h(this,c); } }
/// <summary> /// Indicates vendor specific UPNP error code of 877. /// </summary> public Error_CannotSetContentUri(ProtocolInfoString protocolInfo, string contentUri) : base(877, "Cannot set the contentUri ("+contentUri+") to a string beginning with ("+MediaResource.AUTOMAPFILE+") if the protocolInfo ("+protocolInfo.ToString()+") does not indicate a protocol of \"http-get\"") { this.ContentUri = contentUri; this.ProtocolInfo = protocolInfo; }
/// <summary> /// MediaResources must have a contentURI and a valid protocolInfo string /// at minimum. /// </summary> /// <param name="contentUri">The URI from which the resource can be consumed.</param> /// <param name="protocolInfo">The valid protocolInfo string in the form: "[protocol]:[network]:[mime type]:[info]".</param> public MediaResource(string contentUri, string protocolInfo) { OpenSource.Utilities.InstanceTracker.Add(this); m_ContentUri = contentUri.Trim(); m_ProtocolInfo = new ProtocolInfoString(protocolInfo); }
/// <summary> /// This method is called when an AsyncCall to GetProtocolInfo completes /// </summary> /// <param name="sender"></param> /// <param name="Source"></param> /// <param name="Sink"></param> /// <param name="e"></param> /// <param name="Handle"></param> protected void GetProtocolInfoSink(CpConnectionManager sender, System.String Source, System.String Sink, UPnPInvokeException e, object Handle) { if(e!=null) return; if(Sink=="") return; // This is a temp parser to parse the supported ProtocolInfo values DText p = new DText(); p.ATTRMARK = ","; p[0] = Sink; int len = p.DCOUNT(); ProtocolInfoString istring; for(int i=1;i<=len;++i) { istring = new ProtocolInfoString(p[i]); // Add each individual entry ProtocolInfoList.Add(istring); } if(!this.__Init) { this.__Init = true; // Upon discovery of a renderer, we can't return the renderer to the user // until we at least parsed the supported ProtocolInfo values, otherwise // the user will experience incorrect behavior. Since we have just parsed // these values, we can fire this event. if(this.OnInitialized!=null) OnInitialized(this); } }
private void startMenuItem_Click(object sender, System.EventArgs e) { startMenuItem.Enabled = false; foreach (MenuItem i in pfcMenuItem.MenuItems) {i.Enabled = false;} foreach (MenuItem i in menuItem3.MenuItems) {i.Enabled = false;} InfoStringBox.Enabled = false; device = UPnPDevice.CreateRootDevice(900,1,""); device.UniqueDeviceName = Guid.NewGuid().ToString(); device.StandardDeviceType = "MediaRenderer"; device.FriendlyName = "Media Renderer (" + System.Net.Dns.GetHostName() + ")"; device.HasPresentation = false; device.Manufacturer = "OpenSource"; device.ManufacturerURL = "http://opentools.homeip.net/"; device.PresentationURL = "/"; device.HasPresentation = true; device.ModelName = "AV Renderer"; device.ModelDescription = "Media Renderer Device"; device.ModelURL = new Uri("http://opentools.homeip.net/"); UPnPService ts = new UPnPService(1, "EmptyService", "EmptyService", true, this); ts.AddMethod("NullMethod"); //device.AddService(ts); DText p = new DText(); p.ATTRMARK = "\r\n"; p[0] = this.InfoStringBox.Text; int len = p.DCOUNT(); ProtocolInfoString[] istring = new ProtocolInfoString[len]; for(int i=1;i<=len;++i) { istring[i-1] = new ProtocolInfoString(p[i]); } r = new AVRenderer(MaxConnections, istring, new AVRenderer.ConnectionHandler(NewConnectionSink)); r.OnClosedConnection += new AVRenderer.ConnectionHandler(ClosedConnectionSink); if (supportRecordMenuItem.Checked == false) { r.AVT.RemoveAction_Record(); } if (supportRecordQualityMenuItem.Checked == false) { r.AVT.RemoveAction_SetRecordQualityMode(); } if (supportNextContentUriMenuItem.Checked == false) { r.AVT.RemoveAction_SetNextAVTransportURI(); } if (MaxConnections == 0) { r.Manager.RemoveAction_PrepareForConnection(); r.Manager.RemoveAction_ConnectionComplete(); } r.AVT.GetUPnPService().GetStateVariableObject("CurrentPlayMode").AllowedStringValues = new String[3]{"NORMAL","REPEAT_ALL","INTRO"}; r.Control.GetUPnPService().GetStateVariableObject("A_ARG_TYPE_Channel").AllowedStringValues = new String[3]{"Master","LF","RF"}; r.Control.GetUPnPService().GetStateVariableObject("RedVideoBlackLevel").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("GreenVideoBlackLevel").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("BlueVideoBlackLevel").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("RedVideoGain").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("GreenVideoGain").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("BlueVideoGain").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("Brightness").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("Contrast").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("Sharpness").SetRange((ushort)0,(ushort)100,(ushort)1); r.Control.GetUPnPService().GetStateVariableObject("Volume").SetRange((UInt16)0,(UInt16)100,(ushort)1); device.AddService(r.Control); device.AddService(r.AVT); device.AddService(r.Manager); //device.AddDevice(r); device.StartDevice(); //r.Start(); }
/// <summary> /// Creates a media object. /// </summary> /// <param name="title">The title of the object.</param> /// <param name="file">The full path to the file.</param> /// <returns>Media object.</returns> private static IDvMedia CreateObject(string title, string file) { var fi = new FileInfo(file); var media = DvMediaBuilder.CreateItem(new MediaBuilder.item(title)); string mime, mediaClass; MimeTypes.ExtensionToMimeType(fi.Extension, out mime, out mediaClass); var resInfo = new ResourceBuilder.VideoItem { contentUri = MediaResource.AUTOMAPFILE + fi.FullName, protocolInfo = new ProtocolInfoString("http-get:*:" + mime + ":*"), size = new _ULong((ulong)fi.Length) }; var res = DvResourceBuilder.CreateResource(resInfo, true); res.Tag = fi; media.AddResource(res); if (_mimes.Contains(mime) == false) { _mimes.Add(mime); var ps = new ProtocolInfoString[_mimes.Count]; var i = 0; foreach (var mime2 in _mimes) { ps[i++] = new ProtocolInfoString("http-get:*:" + mime2 + ":*"); } _ms.SourceProtocolInfoSet = ps; } return media; }