public void Rdpei_TouchInputTest_Positive_SingleTouchEvent()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            this.rdpeiSUTControlAdapter.TriggerOneTouchEventOnClient(this.TestContext.TestName);
            // RDPEI running phase
            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_TOUCH_EVENT_PDU ...");
            RDPINPUT_TOUCH_EVENT_PDU touchEventPdu = this.rdpeiServer.ExpectRdpInputTouchEventPdu(waitTime);

            VerifyRdpInputTouchEventPdu(touchEventPdu, true);

            if (isManagedAdapter)
            {
                RdpeiUtility.SendConfirmImage();
            }
        }
Exemple #2
0
        public void Rdpei_TouchControlTest_Positive_Suspend()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            // RDPEI running phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SUSPEND_TOUCH_PDU.");
            RDPINPUT_SUSPEND_TOUCH_PDU suspendPdu = this.rdpeiServer.CreateRdpInputSuspendTouchPdu();

            this.rdpeiServer.SendRdpInputSuspendTouchPdu(suspendPdu);

            this.rdpeiSUTControlAdapter.TriggerContinuousTouchEventOnClient(this.TestContext.TestName);

            // Expect to reveice nothing after sending the RDPINPUT_SUSPEND_TOUCH_PDU message.
            RDPINPUT_PDU pdu = this.rdpeiServer.ExpectRdpInputPdu(waitTime);

            TestSite.Assert.IsNull(pdu, "Client must suspend the transmission of touch frames after receiving a RDPINPUT_SUSPEND_TOUCH_PDU message.");
        }
        /// <summary>
        /// Method to create a RDPINPUT_SC_READY_PDU.
        /// </summary>
        /// <param name="eventId">A 16-bit unsigned integer that identifies the type of the input event PDU.</param>
        /// <param name="pduLength">A 32-bit unsigned integer that specifies the length of the input event PDU in bytes.</param>
        /// <param name="protocolVersion">A 32-bit unsigned integer that specifies the input protocol version.</param>
        /// <returns>The created RDPINPUT_SC_READY_PDU.</returns>
        public RDPINPUT_SC_READY_PDU CreateRdpInputScReadyPdu(EventId_Values eventId = EventId_Values.EVENTID_SC_READY, uint pduLength = 10, RDPINPUT_SC_READY_ProtocolVersion protocolVersion = RDPINPUT_SC_READY_ProtocolVersion.RDPINPUT_PROTOCOL_V100)
        {
            RDPINPUT_SC_READY_PDU pdu = new RDPINPUT_SC_READY_PDU();

            pdu.header.eventId   = eventId;
            pdu.header.pduLength = pduLength;
            pdu.protocolVersion  = protocolVersion;
            return(pdu);
        }
        public void Rdpei_TouchInputTest_Positive_MultiTouchEvent()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            ushort contactCount = (csReadyPdu.maxTouchContacts > 5) ? (ushort)5 : csReadyPdu.maxTouchContacts;

            this.rdpeiSUTControlAdapter.TriggerMultiTouchEventOnClient(this.TestContext.TestName, contactCount);

            // RDPEI running phase
            Site.Log.Add(LogEntryKind.Debug, "Expecting multitouch RDPINPUT_TOUCH_EVENT_PDU ...");
            bool     isFirstFrame            = true;
            DateTime endTime                 = DateTime.Now + waitTime;
            bool     isExpectedFrameReceived = false;

            while (DateTime.Now < endTime && !isExpectedFrameReceived)
            {
                RDPINPUT_TOUCH_EVENT_PDU touchEventPdu = this.rdpeiServer.ExpectRdpInputTouchEventPdu(waitTime);
                Site.Assert.IsNotNull(touchEventPdu, "Client is expected to send to the server a RDPINPUT_TOUCH_EVENT_PDU whose contactCount is {0}.", contactCount);
                VerifyRdpInputTouchEventPdu(touchEventPdu, isFirstFrame);
                if (isFirstFrame)
                {
                    isFirstFrame = false;
                }
                foreach (RDPINPUT_TOUCH_FRAME f in touchEventPdu.frames)
                {
                    if (f.contactCount.ToUShort() == contactCount)
                    {
                        isExpectedFrameReceived = true;
                        break;
                    }
                }
            }
            Site.Assert.IsTrue(isExpectedFrameReceived, "Client is expected to send to the server a RDPINPUT_TOUCH_EVENT_PDU whose contactCount is {0}.", contactCount);
            if (isManagedAdapter)
            {
                RdpeiUtility.SendConfirmImage();
            }
        }
        /// <summary>
        /// Method to send a RDPINPUT_SC_READY_PDU to client.
        /// </summary>
        /// <param name="pdu">A RDPINPUT_SC_READY_PDU structure.</param>
        public void SendRdpInputScReadyPdu(RDPINPUT_SC_READY_PDU pdu)
        {
            byte[] data = PduMarshaler.Marshal(pdu);

            // Sleep some time to avoid this packet to be merged with other packets in TCP level.
            System.Threading.Thread.Sleep(PacketsInterval);
            if (rdpeiDVC == null)
            {
                throw new InvalidOperationException("DVC instance of RDPEI is null, Dynamic virtual channel must be created before sending data.");
            }
            rdpeiDVC.Send(data);
        }
Exemple #6
0
        public void Rdpei_TouchControlTest_Negative_DuplicatedResume()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            // RDPEI running phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SUSPEND_TOUCH_PDU.");
            RDPINPUT_SUSPEND_TOUCH_PDU suspendPdu = this.rdpeiServer.CreateRdpInputSuspendTouchPdu();

            this.rdpeiServer.SendRdpInputSuspendTouchPdu(suspendPdu);

            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_RESUME_TOUCH_PDU.");
            RDPINPUT_RESUME_TOUCH_PDU resumePdu = this.rdpeiServer.CreateRdpInputResumeTouchPdu();

            this.rdpeiServer.SendRdpInputResumeTouchPdu(resumePdu);

            // Send a duplicated resume message to test the client will ignore it, since the Touch Remoting Suspended ADM element is already set to FALSE.
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_RESUME_TOUCH_PDU.");
            this.rdpeiServer.SendRdpInputResumeTouchPdu(resumePdu);

            this.rdpeiSUTControlAdapter.TriggerOneTouchEventOnClient(this.TestContext.TestName);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_TOUCH_EVENT_PDU ...");
            RDPINPUT_TOUCH_EVENT_PDU touchEventPdu = this.rdpeiServer.ExpectRdpInputTouchEventPdu(waitTime);

            VerifyRdpInputTouchEventPdu(touchEventPdu, true);

            if (isManagedAdapter)
            {
                RdpeiUtility.SendConfirmImage();
            }
        }
        public void Rdpei_TouchInputTest_Positive_ContactStateTransition()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            this.rdpeiSUTControlAdapter.TriggerContinuousTouchEventOnClient(this.TestContext.TestName);
            // RDPEI running phase
            this.stateMachine = new TouchContactStateMachine();
            this.stateMachine.Initialize();

            DateTime expireTime = DateTime.Now + waitTime;

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_TOUCH_EVENT_PDU or RDPINPUT_DISMISS_HOVERING_CONTACT_PDU ...");
            bool isFirstFrame = true;

            while (DateTime.Now < expireTime)
            {
                RDPINPUT_PDU inputPdu = this.rdpeiServer.ExpectRdpInputPdu(waitTime);
                // Check the state transition of every contact in every received pdu.
                VerifyAndUpdateContactState(inputPdu, isFirstFrame);
                if (isFirstFrame)
                {
                    isFirstFrame = false;
                }
            }
        }
Exemple #8
0
        public void Rdpei_TouchControlTest_Negative_InvalidResumePduLength()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            // RDPEI running phase

            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SUSPEND_TOUCH_PDU.");
            RDPINPUT_SUSPEND_TOUCH_PDU suspendPdu = this.rdpeiServer.CreateRdpInputSuspendTouchPdu();

            this.rdpeiServer.SendRdpInputSuspendTouchPdu(suspendPdu);

            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_RESUME_TOUCH_PDU with invalid PduLength.");
            RDPINPUT_INVALID_PDU invalidPdu = CreateRdpInputInvalidPdu((ushort)EventId_Values.EVENTID_RESUME_TOUCH, 16, null);

            SendRdpInvalidPdu(invalidPdu);

            // Expect the client to ignore the RDPINPUT_RESUME_TOUCH_PDU with invalid pduLength.
            this.rdpeiSUTControlAdapter.TriggerContinuousTouchEventOnClient(this.TestContext.TestName);

            // Expect to reveice nothing.
            RDPINPUT_PDU pdu = this.rdpeiServer.ExpectRdpInputPdu(waitTime);

            TestSite.Assert.IsNull(pdu, "Client should ignore the RDPINPUT_RESUME_TOUCH_PDU message when the pduLength field is inconsistent with the amount of data read from DVC.");
        }
        public void Rdpei_TouchInputTest_Negative_InvalidScReadyPduLength()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU with PduLength set to 6.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu(EventId_Values.EVENTID_SC_READY, 6);

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            // Expect the client to ignore the RDPINPUT_SC_READY_PDU with invalid pduLength.
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(shortWaitTime);

            Site.Assert.IsNull(csReadyPdu, "The client should ignore the RDPINPUT_SC_READY_PDU message when the pduLength field is inconsistent with the amount of data read from DVC.");
        }
        public void Rdpei_TouchInputTest_Positive_TouchReadiness()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            VerifyRdpInputCsReadyPdu(csReadyPdu);
        }
 /// <summary>
 /// The callback method to receive data from transport layer.
 /// </summary>
 private void OnDataReceived(byte[] data, uint channelID)
 {
     lock (receivedList)
     {
         RDPINPUT_PDU pdu     = new RDPINPUT_PDU();
         bool         fResult = PduMarshaler.Unmarshal(data, pdu);
         if (fResult)
         {
             byte[] pduData = new byte[pdu.header.pduLength];
             Array.Copy(data, pduData, pduData.Length);
             RDPINPUT_PDU msg = pdu;
             if (pdu.header.eventId == EventId_Values.EVENTID_SC_READY)
             {
                 RDPINPUT_SC_READY_PDU request = new RDPINPUT_SC_READY_PDU();
                 if (PduMarshaler.Unmarshal(pduData, request))
                 {
                     msg = request;
                 }
             }
             else if (pdu.header.eventId == EventId_Values.EVENTID_SUSPEND_TOUCH)
             {
                 RDPINPUT_SUSPEND_TOUCH_PDU request = new RDPINPUT_SUSPEND_TOUCH_PDU();
                 if (PduMarshaler.Unmarshal(pduData, request))
                 {
                     msg = request;
                 }
             }
             else if (pdu.header.eventId == EventId_Values.EVENTID_RESUME_TOUCH)
             {
                 RDPINPUT_RESUME_TOUCH_PDU request = new RDPINPUT_RESUME_TOUCH_PDU();
                 if (PduMarshaler.Unmarshal(pduData, request))
                 {
                     msg = request;
                 }
             }
             receivedList.Add(msg);
         }
     }
 }
        public void Rdpei_TouchInputTest_Positive_DismissHoveringContact()
        {
            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            // Trigger the user to determin whether the client device supports proximity. If not, negative value will be returned when using interactive adapter.
            if (this.rdpeiSUTControlAdapter.TriggerDismissHoveringContactPduOnClient(this.TestContext.TestName) < 0)
            {
                TestSite.Assume.Inconclusive("The client device does not support proximity.");
            }
            // RDPEI running phase
            RDPINPUT_TOUCH_EVENT_PDU touchEventPdu = this.rdpeiServer.ExpectRdpInputTouchEventPdu(waitTime);

            this.stateMachine = new TouchContactStateMachine();
            this.stateMachine.Initialize();
            VerifyAndUpdateContactState(touchEventPdu, true);
            // Verify the user input.
            ushort left   = (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopWidth - 160);
            ushort top    = (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopHeight - 120);
            ushort width  = 100;
            ushort height = 60;

            if (touchEventPdu != null && touchEventPdu.frames != null)
            {
                foreach (RDPINPUT_TOUCH_FRAME f in touchEventPdu.frames)
                {
                    foreach (RDPINPUT_CONTACT_DATA d in f.contacts)
                    {
                        int x = d.x.ToInt();
                        int y = d.y.ToInt();
                        if (x >= left && x <= (left + width) && y >= top && y <= (top + height))
                        {
                            TestSite.Assume.Inconclusive("The client device does not support proximity.");
                        }
                    }
                }
            }
            // The client supports proximity, waiting for RDPINPUT_DISMISS_HOVERING_CONTACT_PDU.
            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_DISMISS_HOVERING_CONTACT_PDU ...");
            DateTime endTime = DateTime.Now + waitTime;
            bool     isExpectedFrameReceived = false;

            while (DateTime.Now < endTime && !isExpectedFrameReceived)
            {
                RDPINPUT_PDU pdu = this.rdpeiServer.ExpectRdpInputPdu(waitTime);
                // Intent to check whether the state transition of received RDPINPUT_DISMISS_HOVERING_CONTACT_PDU is valid.
                VerifyAndUpdateContactState(pdu, false);
                if (pdu != null && pdu is RDPINPUT_DISMISS_HOVERING_CONTACT_PDU)
                {
                    isExpectedFrameReceived = true;
                }
            }
            TestSite.Assert.IsTrue(isExpectedFrameReceived, "Client is expected to send RDPINPUT_DISMISS_HOVERING_CONTACT_PDU to the server.");
            if (isManagedAdapter)
            {
                RdpeiUtility.SendConfirmImage();
            }
        }
        public void Rdpei_TouchInputTest_Positive_SingleTouchContactPosition()
        {
            if (isInteractiveAdapter)
            {
                Site.Assume.Inconclusive("This case will not be bun when using interactive client control adapter.");
            }

            Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ...");
            StartRDPConnection();

            Site.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEI ...");
            bool bProtocolSupported = this.rdpeiServer.CreateRdpeiDvc(waitTime);

            TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol.");

            // RDPEI initializing phase
            Site.Log.Add(LogEntryKind.Debug, "Sending a RDPINPUT_SC_READY_PDU.");
            RDPINPUT_SC_READY_PDU scReadyPdu = this.rdpeiServer.CreateRdpInputScReadyPdu();

            this.rdpeiServer.SendRdpInputScReadyPdu(scReadyPdu);

            Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_CS_READY_PDU ...");
            RDPINPUT_CS_READY_PDU csReadyPdu = this.rdpeiServer.ExpectRdpInputCsReadyPdu(waitTime);

            TestSite.Assert.IsTrue(csReadyPdu != null, "Client is expected to send RDPINPUT_CS_READY_PDU to the server.");

            this.rdpeiSUTControlAdapter.TriggerPositionSpecifiedTouchEventOnClient("Rdpei_TouchInputTest_Positive_SingleTouchEvent");
            // RDPEI running phase
            ushort width  = this.rdpbcgrAdapter.CapabilitySetting.DesktopWidth;
            ushort height = this.rdpbcgrAdapter.CapabilitySetting.DesktopHeight;
            // The diameter of the circle to be sent to the client.
            ushort diam   = 64;
            Random random = new Random();

            // The left and top position of the circles to be sent to the client.
            //ushort[] arr = { 0, 0, 0, (ushort)(height - diam), (ushort)(width - diam), 0, (ushort)(width - diam), (ushort)(height - diam), (ushort)(random.Next(width - diam * 2) + diam), (ushort)(random.Next(height - diam * 2) + diam) };
            ushort[] arr          = { 0, 0, 0, (ushort)(height - diam), (ushort)(width - diam), 0, (ushort)(width - diam), (ushort)(height - diam), (ushort)(width / 2 - diam / 2), (ushort)(height / 2 - diam / 2) };
            bool     isFirstFrame = true;

            for (int i = 0; i < 5; i++)
            {
                ushort left = arr[i * 2];
                ushort top  = arr[i * 2 + 1];

                if (isManagedAdapter)
                {
                    RdpeiUtility.SendCircle(diam, Color.Red, left, top);
                }
                Site.Log.Add(LogEntryKind.Debug, "Expecting RDPINPUT_TOUCH_EVENT_PDU ...");

                ushort preLeft = (i == 0) ? (ushort)(width + 1) : arr[(i - 1) * 2];
                ushort preTop  = (i == 0) ? (ushort)(height + 1) : arr[2 * i - 1];
                bool   isExpectedFrameReceived = false;
                while (!isExpectedFrameReceived)
                {
                    RDPINPUT_TOUCH_EVENT_PDU touchEventPdu = this.rdpeiServer.ExpectRdpInputTouchEventPdu(waitTime);
                    VerifyRdpInputTouchEventPdu(touchEventPdu, isFirstFrame);
                    if (isFirstFrame)
                    {
                        isFirstFrame = false;
                    }
                    foreach (RDPINPUT_TOUCH_FRAME f in touchEventPdu.frames)
                    {
                        foreach (RDPINPUT_CONTACT_DATA d in f.contacts)
                        {
                            int contactX = d.x.ToInt();
                            int contactY = d.y.ToInt();
                            // Consume the RDPINPUT_TOUCH_EVENT_PDU received from last touch action.
                            if (contactX >= preLeft && contactX <= preLeft + diam && contactY >= preTop && contactY <= preTop + diam)
                            {
                                continue;
                            }
                            // Touch out of the valid range, send the unexpected position instruction to the client, and fail the case.
                            if (contactX < left || contactX > left + diam || contactY < top || contactY > top + diam)
                            {
                                if (isManagedAdapter)
                                {
                                    ushort l = (contactX < diam / 2) ? (ushort)0 : (contactX > (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopWidth - diam / 2) ? (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopWidth - diam) : (ushort)(contactX - diam / 2));
                                    ushort t = (contactY < diam / 2) ? (ushort)0 : (contactY > (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopHeight - diam / 2) ? (ushort)(rdpbcgrAdapter.CapabilitySetting.DesktopHeight - diam) : (ushort)(contactY - diam / 2));
                                    RdpeiUtility.SendCircle(diam, Color.Green, l, t);

                                    RdpeiUtility.SendInstruction(RdpeiSUTControlData.UnexpectedPositionNotice);
                                }
                                Site.Assert.IsTrue(false, "Client is expected to send a RDPINPUT_TOUCH_EVENT_PDU whose contact position near ({0}, {1}), not ({2}, {3}).", left + diam / 2, top + diam / 2, contactX, contactY);
                            }
                            else
                            {
                                isExpectedFrameReceived = true;
                            }
                        }
                    }
                }
                // Update on the client screen.
                if (isManagedAdapter)
                {
                    RdpeiUtility.SendCircle(diam, Color.Black, left, top);
                }
            }
            if (isManagedAdapter)
            {
                RdpeiUtility.SendConfirmImage();
            }
        }