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> /// Send a Pdu /// </summary> /// <param name="pdu"></param> public void SendRdpeiPdu(RDPINPUT_PDU pdu) { byte[] data = PduMarshaler.Marshal(pdu); if (rdpeiDVC == null) { throw new InvalidOperationException("DVC instance of RDPEI is null, Dynamic virtual channel must be created before sending data."); } rdpeiDVC.Send(data); }
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; } } }
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."); }
/// <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); } } }
/// <summary> /// This method is used to verify the structure of RDPINPUT_TOUCH_EVENT_PDU or RDPINPUT_DISMISS_HOVERING_CONTACT_PDU, and update the contact transition state according to the contacts contained in the message. /// </summary> /// <param name="inputPdu">The input pdu.</param> /// <param name="isFirstFrame">Whether the input pdu is the first pdu that client has transmitted.</param> public void VerifyAndUpdateContactState(RDPINPUT_PDU inputPdu, bool isFirstFrame) { if (inputPdu == null) { return; } if (inputPdu is RDPINPUT_TOUCH_EVENT_PDU) { RDPINPUT_TOUCH_EVENT_PDU pdu = inputPdu as RDPINPUT_TOUCH_EVENT_PDU; Site.Assert.IsNotNull(pdu.header, "The header of RDPINPUT_TOUCH_EVENT_PDU should not be null."); Site.Assert.IsNotNull(pdu.frames, "The array of RDPINPUT_TOUCH_FRAME in RDPINPUT_TOUCH_EVENT_PDU should not be null."); Site.Assert.AreEqual(pdu.header.pduLength, pdu.Length(), "The length of the RDPINPUT_TOUCH_EVENT_PDU message is expected to be the same with the pduLength in header."); Site.Assert.AreEqual((int)pdu.frameCount.ToUShort(), pdu.frames.Length, "The size of the array frames in RDPINPUT_TOUCH_EVENT_PDU is expected to be the same with the frameCount ."); if (isFirstFrame) { Site.Assert.IsTrue(pdu.frames[0].frameOffset.ToULong() == 0, "The field frameOffset of the first frame being transmitted must be set to zero."); } foreach (RDPINPUT_TOUCH_FRAME f in pdu.frames) { Site.Assert.AreEqual((int)f.contactCount.ToUShort(), f.contacts.Length, "The size of the array contacts in RDPINPUT_TOUCH_FRAME is expected to be the same with the contactCount ."); foreach (RDPINPUT_CONTACT_DATA d in f.contacts) { if (((RDPINPUT_CONTACT_DATA_FieldsPresent)(d.fieldsPresent.ToUShort())).HasFlag(RDPINPUT_CONTACT_DATA_FieldsPresent.CONTACT_DATA_CONTACTRECT_PRESENT)) { Site.Assert.IsNotNull(d.contactRectBottom, "The contactRectBottom is not expected to be null when flag CONTACT_DATA_CONTACTRECT_PRESENT in filedsPresent is set."); Site.Assert.IsNotNull(d.contactRectTop, "The contactRectTop is not expected to be null when flag CONTACT_DATA_CONTACTRECT_PRESENT in filedsPresent is set."); Site.Assert.IsNotNull(d.contactRectLeft, "The contactRectLeft is not expected to be null when flag CONTACT_DATA_CONTACTRECT_PRESENT in filedsPresent is set."); Site.Assert.IsNotNull(d.contactRectRight, "The contactRectRight is not expected to be null when flag CONTACT_DATA_CONTACTRECT_PRESENT in filedsPresent is set."); } if (((RDPINPUT_CONTACT_DATA_FieldsPresent)(d.fieldsPresent.ToUShort())).HasFlag(RDPINPUT_CONTACT_DATA_FieldsPresent.CONTACT_DATA_ORIENTATION_PRESENT)) { Site.Assert.IsNotNull(d.orientation, "The orientation is not expected to be null when flag CONTACT_DATA_ORIENTATION_PRESENT in filedsPresent is set."); } if (((RDPINPUT_CONTACT_DATA_FieldsPresent)(d.fieldsPresent.ToUShort())).HasFlag(RDPINPUT_CONTACT_DATA_FieldsPresent.CONTACT_DATA_PRESSURE_PRESENT)) { Site.Assert.IsNotNull(d.pressure, "The orientation is not expected to be null when flag CONTACT_DATA_PRESSURE_PRESENT in filedsPresent is set."); } Site.Assert.IsTrue(Enum.IsDefined(typeof(ValidStateFlagCombinations), d.contactFlags.ToUInt()), "The value of contactFlags does not contain a valid combination of the contact state flags."); ValidStateFlagCombinations temp = (ValidStateFlagCombinations)(d.contactFlags.ToUInt()); byte result = stateMachine.UpdateContactsMap(d.contactId, temp, d.x.ToInt(), d.y.ToInt()); Site.Assert.AreNotEqual(result, 1, "The contact state transition is invalid."); Site.Assert.AreNotEqual(result, 2, "The contact position cannot change when transitioning from 'engaged' state to 'hovering' or 'out of range' state."); } } } else if (inputPdu is RDPINPUT_DISMISS_HOVERING_CONTACT_PDU) { RDPINPUT_DISMISS_HOVERING_CONTACT_PDU pdu = inputPdu as RDPINPUT_DISMISS_HOVERING_CONTACT_PDU; Site.Assert.IsNotNull(pdu.header, "The header of RDPINPUT_DISMISS_HOVERING_CONTACT_PDU should not be null."); Site.Assert.AreEqual(pdu.header.eventId, EventId_Values.EVENTID_DISMISS_HOVERING_CONTACT, "The eventId in the header of RDPINPUT_DISMISS_HOVERING_CONTACT_PDU is expected to be EVENTID_DISMISS_HOVERING_CONTACT."); Site.Assert.AreEqual(pdu.header.pduLength, pdu.Length(), "The length of the RDPINPUT_DISMISS_HOVERING_CONTACT_PDU message is expected to be the same with the pduLength in header."); TouchContactAttribute attr; if (stateMachine.contactStateMap.TryGetValue(pdu.contactId, out attr)) { Site.Assert.AreEqual(attr.state, TouchContactState.Hovering, "The contact {0} is expected to be in hovering state.", pdu.contactId); stateMachine.UpdateContactsMap(pdu.contactId, ValidStateFlagCombinations.UPDATE, 0, 0); } else { Site.Assert.IsTrue(false, "The contact {0} is expected to be in hovering state, but it's out of range.", pdu.contactId); } } else { Site.Assert.IsTrue(false, "Unexpected message."); } }
/// <summary> /// Expect a RDPINPUT_TOUCH_EVENT_PDU or a RDPINPUT_DISMISS_HOVERING_CONTACT_PDU or a RDPINPUT_CS_READY_PDU. /// </summary> /// <param name="timeout">TimeOut</param> /// <returns>A RDPINPUT_TOUCH_EVENT_PDU or a RDPINPUT_DISMISS_HOVERING_CONTACT_PDU or a RDPINPUT_CS_READY_PDU instance.</returns> public RDPINPUT_PDU ExpectRdpInputPdu(TimeSpan timeout) { RDPINPUT_PDU pdu = ExpectRdpeiPdu <RDPINPUT_PDU>(timeout); return(pdu); }
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(); } }