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>
        /// 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 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>
        /// 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>
        /// 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);
            }
        }
        /// <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());
        }
        /// <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());
                 * }
                 */
            }
        }
        /// <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);
                }
            }
        }
        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);
                }
            }
        }
 protected void PeriodicRenewFailedSink(CpConnectionManager sender)
 {
     EventRenewalFailureEvent.Fire(this);
 }
        /// <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);
        }
 private void CurrentConnectionIDs_P4C(CpConnectionManager sender, string NewVal)
 {
     Ev.Set();
 }
        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;
        }