/// <summary> /// Executes when the ConnectionManager events for the first time. /// </summary> /// <param name="sender"></param> /// <param name="newVal"></param> private void Sink_OnCmEvented(CpConnectionManager sender, string newVal) { sender.OnStateVariable_SourceProtocolInfo -= new CpConnectionManager.StateVariableModifiedHandler_SourceProtocolInfo(this.Sink_OnCmEvented); string udn = sender.GetUPnPService().ParentDevice.UniqueDeviceName; lock (LockHashes) { InitStatus status = (InitStatus) UdnToInitStatus[udn]; if (status != null) { status.ZeroMeansDone--; status.EventedCM = true; this.ProcessInitStatusChange(udn); } } }
/// <summary> /// Executes when the ConnectionManager service returns on the subscribe status. /// </summary> /// <param name="sender"></param> /// <param name="success"></param> private void Sink_OnCmServiceSubscribe(CpConnectionManager sender, bool success) { sender.OnSubscribe -= new CpConnectionManager.SubscribeHandler(this.Sink_OnCmServiceSubscribe); string udn = sender.GetUPnPService().ParentDevice.UniqueDeviceName; lock (LockHashes) { InitStatus status = (InitStatus) UdnToInitStatus[udn]; if (status != null) { status.ZeroMeansDone--; status.SubcribeCM = success; this.ProcessInitStatusChange(udn); } } }
/// <summary> /// This method is called whenever we need to inspect a list of ConnectionIDs /// to see if any of them are new /// </summary> /// <param name="sender"></param> /// <param name="IDString"></param> /// <param name="e"></param> /// <param name="Handle"></param> protected void IDSink(CpConnectionManager sender, string IDString, UPnPInvokeException e, object Handle) { if((e!=null) || (IDString=="")) return; // This is a temp parser that will parse the CSV list of IDs DText p = new DText(); p.ATTRMARK = ","; p[0] = IDString; int len = p.DCOUNT(); for(int i=1;i<=len;++i) { // bool FOUND = false; int cid = int.Parse(p[i].Trim()); // lock(InstanceList) // { // foreach(AVConnection _AVC in InstanceList) // { // if(_AVC.ConnectionID == cid) // { // FOUND = true; // break; // } // } // } lock(this.CreateConnectionLock) { if(this.PendingCreateConnection==0) { ConnectionManager.GetCurrentConnectionInfo(cid,null,new CpConnectionManager.Delegate_OnResult_GetCurrentConnectionInfo(ConnectionInfoSink)); } else { // We possible need to wait a maximum of 30 seconds, just in case events arrive // that involve this connection ID. When/if that happens, we will remove this // object from the monitor, and continue directly. this.ConnectionMonitor.Add(cid,30); } } } }
/// <summary> /// Creates a programmer-friendly object for using a device /// that happens implement a MediaServer. /// </summary> /// <param name="device"></param> public CpMediaServer(UPnPDevice device) { UPnPService sCM = device.GetServices(CpConnectionManager.SERVICE_NAME)[0]; UPnPService sCD = device.GetServices(CpContentDirectory.SERVICE_NAME)[0]; CpConnectionManager cpCM = new CpConnectionManager(sCM); CpContentDirectory cpCD = new CpContentDirectory(sCD); UDN = device.UniqueDeviceName; if ( (cpCD.HasAction_GetSearchCapabilities == false) || (cpCD.HasAction_GetSortCapabilities == false) || (cpCD.HasAction_GetSystemUpdateID == false) || (cpCD.HasAction_Browse == false) ) { throw new UPnPCustomException(0, "MediaServer does not implement minimum features."); } this.m_ConnectionManager = cpCM; this.m_ContentDirectory = cpCD; //create a virtualized root container with the desired settings m_Root = new CpRootContainer(this); m_Root.UDN = device.UniqueDeviceName; }
/// <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); } }
/// <summary> /// This method is called when an Async call to PrepareForConnection returns. Only /// the AVPlayList class will ever call that method. /// </summary> /// <param name="sender"></param> /// <param name="RemoteProtocolInfo"></param> /// <param name="PeerConnectionManager"></param> /// <param name="PeerConnectionID"></param> /// <param name="Direction"></param> /// <param name="ConnectionID"></param> /// <param name="AVTransportID"></param> /// <param name="RcsID"></param> /// <param name="e"></param> /// <param name="Handle"></param> protected void PrepareForConnectionSink(CpConnectionManager sender, System.String RemoteProtocolInfo, System.String PeerConnectionManager, System.Int32 PeerConnectionID, CpConnectionManager.Enum_A_ARG_TYPE_Direction Direction, System.Int32 ConnectionID, System.Int32 AVTransportID, System.Int32 RcsID, UPnPInvokeException e, object Handle) { AVConnection c = null; bool IsNew = true; if(e!=null) { // Since only the AVPlayList class will call PrepareForConnection, we need to fire // this other event, because it's too early to notify the user. Only AVPlayList needs // to know about this, so it can continue to setup the connection for the user OnCreateConnectionFailedEvent2.Fire(this,AVRenderer.CreateFailedReason.CREATE_ATTEMPT_DENIED,Handle); return; } lock(InstanceList) { foreach(AVConnection a in InstanceList) { if(a.ConnectionID==ConnectionID) { // We Already Have this ID From somewhere IsNew = false; c = a; break; } } if(IsNew==true) { // Does not Exist c = new AVConnection(MainDevice, AVTransportID, RcsID, ConnectionID,new AVConnection.OnReadyHandler(_ReadySink), Handle); c._Parent = this; InstanceList.Add(c); } } if(IsNew==true) { // Wait for Ready event from the AVConnection, since we can't return it // until it is initialized. } else { // Recycled OnRecycledConnectionEvent2.Fire(this,c,Handle); } }
protected void PeriodicRenewFailedSink(CpConnectionManager sender) { EventRenewalFailureEvent.Fire(this); }
/// <summary> /// This method is triggered whenever a ConnectionManagerEvent arrives, which tells us /// all of the current ConnectionIDs /// </summary> /// <param name="sender">The CpConnectionManager class that sent the event</param> /// <param name="CurrentIDs">A CSV list of ConnectionIDs</param> protected void ConnectionIDEventSink(CpConnectionManager sender, string CurrentIDs) { // We need to return immediately if this flag is set. // This flag is only set if PrepareForConnection in not implemented on this // renderer, in which case, there will be a default ConnectionID of 0, which // must never disappear. if(DontEverDelete == true) return; // This is a temp collection used to create an index of the ConnectionIDs that // were recieved in this event Hashtable h = new Hashtable(); // This is a temp parser used to parse the CSV list of IDs DText p = new DText(); p.ATTRMARK = ","; if(CurrentIDs!="") { p[0] = CurrentIDs; int len = p.DCOUNT(); for(int i=1;i<=len;++i) { // Adding a ConnectionID into the temp collection h[Int32.Parse(p[i])] = ""; } } // Lets find ones that were removed first foreach(AVConnection a in Connections) { if(h.ContainsKey(a.ConnectionID)==false) { // This ID was removed InstanceList.Remove(a); a.Dispose(); OnRemovedConnectionEvent.Fire(this,a,Guid.NewGuid().GetHashCode()); } } // Now lets look for new ones... This is easy IDSink(sender, CurrentIDs,null,Guid.NewGuid().GetHashCode()); }
protected void ConnectionInfoSink(CpConnectionManager sender, System.Int32 ConnectionID, System.Int32 RcsID, System.Int32 AVTransportID, System.String ProtocolInfo, System.String PeerConnectionManager, System.Int32 PeerConnectionID, CpConnectionManager.Enum_A_ARG_TYPE_Direction Direction, CpConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus Status, UPnPInvokeException e, object Handle) { if(e!=null) return; AVConnection av=null; lock(InstanceList) { foreach(AVConnection a in InstanceList) { if(a.ConnectionID==ConnectionID) { av = a; break; } } if(av==null) { av = new AVConnection(MainDevice, AVTransportID, RcsID, ConnectionID,new AVConnection.OnReadyHandler(ReadySink), Handle); av._Parent = this; InstanceList.Add(av); } else { return; // Don't need to trigger event } } // Wait for Ready before sending OnCreateConnection }
/// <summary> /// This constructor is called with the UPnPDevice that contains the services of a MediaRenderer device. /// </summary> /// <param name="device">The UPnPDevice</param> public AVRenderer(UPnPDevice device) { OpenSource.Utilities.InstanceTracker.Add(this); this.ConnectionMonitor.OnExpired += new LifeTimeMonitor.LifeTimeHandler(ConnectionMonitorSink); MainDevice = device; ConnectionManager = new CpConnectionManager(device.GetServices(CpConnectionManager.SERVICE_NAME)[0]); ConnectionManager.OnStateVariable_CurrentConnectionIDs += new CpConnectionManager.StateVariableModifiedHandler_CurrentConnectionIDs(ConnectionIDEventSink); ConnectionManager._subscribe(90); //TODO: Fails to compile after using generated code from DeviceBuilderV23. Seems like CpConnectionManager.PeriodicRenewFailedHandler is no longer defined? //ConnectionManager.OnPeriodicRenewFailed += new CpConnectionManager.PeriodicRenewFailedHandler(PeriodicRenewFailedSink); // Grab initial state of the ConnectionManager Service if(ConnectionManager.HasAction_GetProtocolInfo) { ConnectionManager.GetProtocolInfo(null,new CpConnectionManager.Delegate_OnResult_GetProtocolInfo(GetProtocolInfoSink)); } if(ConnectionManager.HasAction_GetCurrentConnectionIDs) { ConnectionManager.GetCurrentConnectionIDs(null,new CpConnectionManager.Delegate_OnResult_GetCurrentConnectionIDs(IDSink)); } if(ConnectionManager.HasAction_PrepareForConnection==false) { lock(InstanceList) { AVConnection ac = new AVConnection(MainDevice,0,0,0,new AVConnection.OnReadyHandler(ReadySink), null); ac._Parent = this; DontEverDelete = true; if(InstanceList.Count==0) InstanceList.Add(ac); } /* Wait for Ready if(InstanceList.Count>0) { if(OnCreateConnection!=null) OnCreateConnection(this,(AVConnection)InstanceList[0],Guid.NewGuid().GetHashCode()); } */ } }
protected void InitialState_GetCurrentConnectionInfoSink(CpConnectionManager sender, System.Int32 ConnectionID, System.Int32 RcsID, System.Int32 AVTransportID, System.String ProtocolInfo, System.String PeerConnectionManager, System.Int32 PeerConnectionID, CpConnectionManager.Enum_A_ARG_TYPE_Direction Direction, CpConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus Status, UPnPInvokeException e, object __tag) { this.ProtocolInfoString = ProtocolInfo; bool OK = false; lock(this) { --StateCounter; if(StateCounter==0) { this.UpdateCurrentItem(); OK = true; } } if(OK) if(OnReady!=null) OnReady(this, Tag); }
/// <summary> /// This is called when GetCurrentConnectionInfo completes. /// </summary> /// <param name="sender"></param> /// <param name="ConnectionID"></param> /// <param name="RcsID"></param> /// <param name="AVTransportID"></param> /// <param name="ProtocolInfo"></param> /// <param name="PeerConnectionManager"></param> /// <param name="PeerConnectionID"></param> /// <param name="Direction"></param> /// <param name="Status"></param> /// <param name="e"></param> /// <param name="Tag"></param> protected void ConnectionInfoSink(CpConnectionManager sender, System.Int32 ConnectionID, System.Int32 RcsID, System.Int32 AVTransportID, System.String ProtocolInfo, System.String PeerConnectionManager, System.Int32 PeerConnectionID, CpConnectionManager.Enum_A_ARG_TYPE_Direction Direction, CpConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus Status, UPnPInvokeException e, object Tag) { if(e!=null) return; MediaResource = ResourceBuilder.CreateResource(MediaResource.ContentUri,ProtocolInfo); if(OnMediaResourceChanged!=null) OnMediaResourceChanged(this,MediaResource); }
/// <summary> /// This construct is only called by the AVRenderer object. /// </summary> /// <param name="device"></param> /// <param name="AVTransportID"></param> /// <param name="RenderingControlID"></param> /// <param name="ConnectionID"></param> /// <param name="ReadyCallback"></param> /// <param name="StateObject"></param> internal AVConnection(UPnPDevice device, int AVTransportID, int RenderingControlID, Int32 ConnectionID, AVConnection.OnReadyHandler ReadyCallback, object StateObject) { OpenSource.Utilities.InstanceTracker.Add(this); this.Tag = StateObject; this.OnReady += ReadyCallback; FriendlyName = device.FriendlyName; Identifier = device.UniqueDeviceName + ":" + ConnectionID.ToString(); AVTid = AVTransportID; RCid = RenderingControlID; CMid = ConnectionID; AVTransport = new CpAVTransport(device.GetServices(CpAVTransport.SERVICE_NAME)[0]); RenderingControl = new CpRenderingControl(device.GetServices(CpRenderingControl.SERVICE_NAME)[0]); ConnectionManager = new CpConnectionManager(device.GetServices(CpConnectionManager.SERVICE_NAME)[0]); if(RenderingControl.HasStateVariable_Volume) { // If the renderer has defined ranges, use those if(RenderingControl.HasMaximum_Volume) { MaxVolume = (UInt16)RenderingControl.Maximum_Volume; } else { MaxVolume = UInt16.MaxValue; } if(RenderingControl.HasMinimum_Volume) { MinVolume = (UInt16)RenderingControl.Minimum_Volume; } else { MinVolume = UInt16.MinValue; } } lock(this) { if(AVTransport.HasStateVariable_LastChange) { // Hook up to the LastChange event of AVTransport ++this.StateCounter; AV_LastChange = new AVTransportLastChange(AVTransport,device.UniqueDeviceName, AVTid, new AVTransportLastChange.ReadyHandler(AVTLC)); AV_LastChange.OnCurrentPositionChanged += new AVTransportLastChange.VariableChangeHandler(PositionSink); AV_LastChange.OnPlayStateChanged += new AVTransportLastChange.VariableChangeHandler(PlayStateSink); AV_LastChange.OnAVTransportURIChanged += new AVTransportLastChange.VariableChangeHandler(AVTransportURISink); AV_LastChange.OnCurrentTrackChanged += new AVTransportLastChange.VariableChangeHandler(TrackChangedSink); AV_LastChange.OnNumberOfTracksChanged += new AVTransportLastChange.VariableChangeHandler(NumberOfTracksChangedSink); AV_LastChange.OnTrackURIChanged += new AVTransportLastChange.VariableChangeHandler(TrackURIChangedSink); AV_LastChange.OnCurrentURIMetaDataChanged += new AVTransportLastChange.VariableChangeHandler(URIMetaDataChangedSink); AV_LastChange.OnCurrentPlayModeChanged += new AVTransportLastChange.VariableChangeHandler(CurrentPlayModeChangedSink); AV_LastChange.OnTransportStatusChanged += new AVTransportLastChange.VariableChangeHandler(TransportStatusChangedSink); } if(RenderingControl.HasStateVariable_LastChange) { // Hook up to the LastChange event of RenderingControl ++this.StateCounter; RC_LastChange = new RenderingControlLastChange(RenderingControl,device.UniqueDeviceName, RCid, new RenderingControlLastChange.OnReadyHandler(RCLC)); RC_LastChange.OnMuteChanged += new RenderingControlLastChange.VariableChangeHandler(MuteSink); RC_LastChange.OnVolumeChanged += new RenderingControlLastChange.VariableChangeHandler(VolumeSink); } /* Get ProtocolInfo Value of current connection */ ++this.StateCounter; ConnectionManager.GetCurrentConnectionInfo(ConnectionID,this.GetHashCode(),new CpConnectionManager.Delegate_OnResult_GetCurrentConnectionInfo(InitialState_GetCurrentConnectionInfoSink)); } RenderingControl._subscribe(500); AVTransport._subscribe(500); }
public override void Start(UPnPDevice device) { UPnPTestStates Master = UPnPTestStates.Pass; TestDevice = device; UPnPDevice d = device; UPnPService[] services = d.GetServices(CpConnectionManager.SERVICE_NAME); if (services == null || services.Length == 0) { enabled = false; return; } CM = new CpConnectionManager(services[0]); string SOURCE=""; string SINK=""; DText parser = new DText(); StartCountDown(0,90); try { CM.Sync_GetProtocolInfo(out SOURCE,out SINK); } catch(UPnPInvokeException) { Results.Add("Connection Handler Test was aborted because GetProtocolInfo FAILED"); SetState("Connection Handling",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } AbortCountDown(); parser.ATTRMARK = ","; parser.MULTMARK = ":"; bool OK = true; if(ConnectionManagerEventsTest()==false) { Results.Add("Connection Handler Test was aborted because of invalid/missing events"); SetState("Connection Handling",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } if(SINK!="") { parser[0] = SINK; TotalTime = parser.DCOUNT()*120; CurrentTime = 0; for(int i=1;i<=parser.DCOUNT();++i) { if(parser.DCOUNT(i)!=4) { // Invalid Format OK = false; AddEvent(LogImportance.Critical,"Connection Handling"," Protocol Info String [" + parser[i] + "] is not in a valid format"); } } if(OK) { AddEvent(LogImportance.Remark,"Connection Handling"," Protocol Info Strings are in the correct format"); } else { Results.Add("Connection Handler Test was aborted because of invalid Protocol Info Strings"); SetState("Connection Handling",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } if(CM.HasAction_PrepareForConnection) { for(int i=1;i<=parser.DCOUNT();++i) { if(PrepareForConnectionTest_SINK(parser[i])==false) { OK = false; } } } } if(OK) { Results.Add("Connection Handler Test PASSED"); SetState("Connection Handling",UPnPTestStates.Pass); } else { Results.Add("Connection Handler Test FAILED"); SetState("Connection Handling",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } OK = true; UPnPService[] _AVT = d.GetServices(CpAVTransport.SERVICE_NAME); if(_AVT.Length!=0) { // AVT Tests AVT = new CpAVTransport(_AVT[0]); if(!Test_AVTransport_LastChange()) OK = false; } if(OK) { Results.Add("Event Formatting PASSED"); SetState("Event Formatting",UPnPTestStates.Pass); } else { Results.Add("Event Formatting FAILED"); SetState("Event Formatting",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } OK = true; _AVT = d.GetServices(CpAVTransport.SERVICE_NAME); if(_AVT.Length!=0) { // AVT Tests AVT = new CpAVTransport(_AVT[0]); if(!Test_AVTransport_StateVariables()) OK = false; } if (OK) { Results.Add("StateVariable Values NOT TESTED (Not implemented)"); SetState("StateVariable Values",UPnPTestStates.Pass); } else { Results.Add("StateVariable Values FAILED"); SetState("StateVariable Values",UPnPTestStates.Failed); Master = UPnPTestStates.Failed; } // this.HTTP_ScenarioTest(); state = Master; }
private void CurrentConnectionIDs_P4C(CpConnectionManager sender, string NewVal) { Ev.Set(); }