/// <summary>
        /// This method is used to trigger client do a screenshot and transfer the captured image to the server, this method will save the captured image on filepath
        /// </summary>
        /// <param name="filePath">Filepath to save captured image</param>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int CaptureScreenShot(string filePath)
        {
            if (!controlHandler.IsUsingTCP)
            {
                this.Site.Assume.Inconclusive("ScreenShot control method needs to transfer big data, only available when using TCP transport");
            }
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            byte[] payload = null;

            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.SCREEN_SHOT,
                        reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            if (controlHandler.OperateSUTControl(requestMessage, false, out resposePayload) > 0)
            {
                DecodeBitmapBinary(resposePayload, filePath);
                return 1;
            }
            else
            {
                return -1;
            }
        }
        /// <summary>
        /// This method is used to trigger the RDPINPUT_DISMISS_HOVERING_CONTACT_PDU message.
        /// </summary>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int TriggerDismissHoveringContactPduOnClient()
        {
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            byte[] payload = null;

            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.TOUCH_EVENT_DISMISS_HOVERING_CONTACT,
                reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// This method is used to trigger continuous touch events on the client.
        /// </summary>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int TriggerContinuousTouchEventOnClient()
        {
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            byte[] payload = BitConverter.GetBytes((uint)singleTouchTimes);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(payload);
            }

            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.TOUCH_EVENT_SINGLE,
                reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// This method is only used by managed adapter. This method is used to touch events at specified position. 
        /// </summary>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int TriggerPositionSpecifiedTouchEventOnClient()
        {
            // this interface need some updates, should contains an input
            Point[] points = new Point[5];
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            List<byte> payloadList = new List<byte>();
            byte[] valueByte = BitConverter.GetBytes((uint)points.Length);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(valueByte);
            }
            payloadList.AddRange(valueByte);

            foreach (Point point in points)
            {
                byte[] xBytes = BitConverter.GetBytes(point.X);
                byte[] yBytes = BitConverter.GetBytes(point.Y);
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(xBytes);
                    Array.Reverse(yBytes);
                }
                payloadList.AddRange(xBytes);
                payloadList.AddRange(yBytes);
            }
            byte[] payload = payloadList.ToArray();
            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.TOUCH_EVENT_SINGLE,
                reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// Trigger SUT to start a RDP Connection
        /// </summary>
        /// <param name="payload">Payload of SUT control request message</param>
        /// <param name="helpMessage">helpMessage of SUT control request message</param>
        /// <returns></returns>
        private int Start_RDP_Connection(byte[] payload, string helpMessage)
        {
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.START_RDP_CONNECTION,
                        reqId, helpMessage, payload);

            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// This method is used to trigger the client to server input events. 
        /// </summary>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int TriggerInputEvents()
        {
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            RDPSUTControl_BasicInputFlag inputFlag = RDPSUTControl_BasicInputFlag.Keyboard_Event | RDPSUTControl_BasicInputFlag.Unicode_Keyboard_Event
                | RDPSUTControl_BasicInputFlag.Mouse_Event | RDPSUTControl_BasicInputFlag.Extended_Mouse_Event
                | RDPSUTControl_BasicInputFlag.Client_Synchronize_Event | RDPSUTControl_BasicInputFlag.Client_Refresh_Rect
                | RDPSUTControl_BasicInputFlag.Client_Suppress_Output;

            byte[] payload = BitConverter.GetBytes((uint)inputFlag);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(payload);
            }

            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.BASIC_INPUT,
                reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// This method is used to trigger RDP client to close all RDP connection to a server for clean up.
        /// </summary>
        /// <returns>Negative values indicate the operation is failed, otherwise, successful.</returns>
        public int TriggerClientDisconnectAll()
        {
            // Get help message
            string helpMessage = CommonUtility.GetHelpMessage(interfaceFullName);
            // Create payload
            byte[] payload = null;

            // Create request message
            ushort reqId = controlHandler.GetNextRequestId();
            SUT_Control_Request_Message requestMessage = new SUT_Control_Request_Message(SUTControl_TestsuiteId.RDP_TESTSUITE, (ushort)RDPSUTControl_CommandId.CLOSE_RDP_CONNECTION,
                reqId, helpMessage, payload);

            //Send the request and get response if necessary
            byte[] resposePayload = null;
            return controlHandler.OperateSUTControl(requestMessage, false, out resposePayload);
        }
        /// <summary>
        /// Send SUT control request message to SUT agent and get the response is necessary
        /// </summary>
        /// <param name="requestMessage">SUT Control Request Message</param>
        /// <param name="ResponseNeeded">Whether response is needed, if true, must get a response, if false, apply the value of alwaysNeedResponse</param>
        /// <param name="payload">out parameter, is the payload of response</param>
        /// <returns></returns>
        public int OperateSUTControl(SUT_Control_Request_Message requestMessage, bool ResponseNeeded, out byte[] payload)
        {
            payload = null;

            foreach (IPEndPoint agentEndpoint in AgentList)
            {
                if (transport.Connect(timeout, agentEndpoint))
                {
                    transport.SendSUTControlRequestMessage(requestMessage);

                    if (alwaysNeedResponse || ResponseNeeded)
                    {
                        //expect response only when alwaysNeedResponse is true
                        SUT_Control_Response_Message responseMessage = transport.ExpectSUTControlResponseMessage(timeout, requestMessage.requestId);

                        if (responseMessage != null)
                        {
                            if (responseMessage.resultCode == (uint)SUTControl_ResultCode.SUCCESS)
                            {
                                transport.Disconnect();
                                payload = responseMessage.payload;
                                this.Site.Log.Add(LogEntryKind.Comment, "RDP SUT Control Protocol Adapter: CommandId is {0}: Success, agent: {1}.", requestMessage.commandId, agentEndpoint.ToString());
                                return 1;
                            }
                            else
                            {
                                string errorMessage = (responseMessage.errorMessage != null) ? responseMessage.errorMessage : "";
                                this.Site.Log.Add(LogEntryKind.Comment, "RDP SUT Control Protocol Adapter: CommandId is {0}: error in response: {1}, error message: {2}", requestMessage.commandId, agentEndpoint.ToString(), errorMessage);
                            }
                        }
                        else
                        {
                            this.Site.Log.Add(LogEntryKind.Comment, "RDP SUT Control Protocol Adapter: CommandId is {0}: Not get response from agent: {1}.", requestMessage.commandId, agentEndpoint.ToString());
                        }
                    }
                    transport.Disconnect();
                }
                else
                {
                    this.Site.Log.Add(LogEntryKind.Comment, "RDP SUT Control Protocol Adapter: CommandId is {0}: Cannot connect to the agent: {1}.", requestMessage.commandId, agentEndpoint.ToString());
                }

            }
            if (alwaysNeedResponse || ResponseNeeded)
            {
                // if alwaysNeedResponse is true, all response return failure
                return -1;
            }
            else
            {
                // if alwaysNeedReponse is false, have send request to all Agents, return 1 for success
                return 1;
            }
        }