예제 #1
0
        /// <summary>
        /// Sends the command to the specified target. The command sends additional data following the initial packet.
        /// </summary>
        /// <param name="target">The target to which to send the command.</param>
        /// <param name="taskData">If non-<c>null</c>, execution data to update for error reporting.</param>
        /// <param name="sourceDataStream">The stream containing the additional data to send to the target. If this value is null, no additional data needs to be sent.</param>
        /// <param name="onSuccess">Action to execute upon successful command completion.</param>
        /// <returns><c>true</c> if the command and its data were successfully sent, <c>false</c> otherwise.</returns>
        protected bool ExecuteCommandWithData(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData, System.IO.Stream sourceDataStream, Action onSuccess)
        {
            bool succeeded = false;

            ExecuteCore <bool>(target, taskData, sourceDataStream, null, onSuccess, out succeeded);
            return(succeeded);
        }
예제 #2
0
        public static void LogPortMessage(this IStreamConnection port, string message)
        {
            var portName = "<null>";

            if (port != null)
            {
                portName = port.Name;
                port.Log(message);
            }
            LogPortMessageToDebugger(message, portName);
        }
예제 #3
0
        /// <summary>
        /// Sends the command to the specified target.
        /// </summary>
        /// <typeparam name="T">The data type of the response data from the command.</typeparam>
        /// <param name="target">The target to which to send the command.</param>
        /// <param name="taskData">If non-<c>null</c>, execution data to update for error reporting.</param>
        /// <returns>The data returned by the command. In the case of commands that do not send additional results, this will be the same as the succeeded result.</returns>
        public T Execute <T>(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData)
        {
            bool succeeded = false;
            var  result    = (T)Execute(target, taskData, out succeeded);

            if (!succeeded)
            {
                throw new InvalidOperationException(string.Format(Resources.Strings.DeviceCommandFailed_SimpleFormat, Command), taskData.Error);
            }
            return(result);
        }
예제 #4
0
        private void SendCommandPayload(IStreamConnection target, System.IO.Stream sourceDataStream, System.IO.MemoryStream resultStream)
        {
            if ((target != null) && target.WriteStream.CanTimeout)
            {
                var minTimeout = target.EstimateDataTransferTime(sourceDataStream.Length);
                target.WriteStream.WriteTimeout = (int)(minTimeout * 4);
            }
            sourceDataStream.CopyTo(target.WriteStream);
            var commandBytesWritten = (int)sourceDataStream.Length;

            sourceDataStream.Seek(0, System.IO.SeekOrigin.Begin);
            sourceDataStream.CopyTo(resultStream);
        }
예제 #5
0
        internal void Connect(string username, string apikey, bool secure = true)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

            var protocol = (secure) ? "wss" : "ws";
            var url      = String.Format("{0}://{1}/multi?statuses=true&username={2}&api_key={3}", protocol, _domain, username, apikey);

            Trace.TraceInformation("Connecting to " + url);

            _connection                  = GetConnection(url);
            _connection.Opened          += _connection_Opened;
            _connection.Error           += _connection_Error;
            _connection.Closed          += _connection_Closed;
            _connection.MessageReceived += _connection_MessageReceived;
            _connection.Open();
        }
예제 #6
0
        internal void Connect(string username, string apikey, bool secure = true)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

            var protocol = (secure) ? "wss" : "ws";
            var url = String.Format("{0}://{1}/multi?statuses=true&username={2}&api_key={3}", protocol, _domain, username, apikey);

            Trace.TraceInformation("Connecting to " + url);

            _connection = GetConnection(url);
            _connection.Opened += _connection_Opened;
            _connection.Error += _connection_Error;
            _connection.Closed += _connection_Closed;
            _connection.MessageReceived += _connection_MessageReceived;
            _connection.Open();
        }
예제 #7
0
        private T ExecuteCore <T>(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData, System.IO.Stream sourceDataStream, Func <System.IO.Stream, T> inflate, Action onSuccess, out bool succeeded)
        {
            succeeded = false;
            var errorDetail = string.Empty;
            var response    = default(T);
            var timedOut    = false;

#if REPORT_COMMAND_PERFORMANCE
            var stopwatch    = System.Diagnostics.Stopwatch.StartNew();
            var reportSuffix = sourceDataStream == null ? "RESP" : "DATA";
            try
            {
#endif // REPORT_COMMAND_PERFORMANCE
            using (target.SetInUse(UpdatePortChunkSizeConfigurations))
            {
                if (taskData != null)
                {
                    taskData.CurrentlyExecutingCommand = Command;
                }
                lock (_lock)
                {
                    target.LogPortMessage("EXECUTE: " + Command);
                    Exception exception            = null;
                    var       previousWriteTimeout = -1;
                    if (target.WriteStream.CanTimeout)
                    {
                        previousWriteTimeout = target.WriteStream.WriteTimeout;
                    }
                    try
                    {
                        using (var writer = new INTV.Shared.Utility.ASCIIBinaryWriter(target.WriteStream))
                        {
                            _dataSent = string.Empty;
                            var commandBytesWritten = Serialize(writer);
                            target.LogPortMessage("EXECUTE: wrote " + commandBytesWritten + " bytes for command: " + Command + ", data sent: " + _dataSent);
                        }

                        if (target.ReadStream.CanTimeout)
                        {
                            target.ReadStream.ReadTimeout = ResponseTimeout;
                        }

                        using (var reader = new INTV.Shared.Utility.ASCIIBinaryReader(target.ReadStream))
                        {
                            using (var resultStream = new System.IO.MemoryStream())
                            {
                                var ack = GetCommandAcknowledgement(reader, Command, ref errorDetail, out timedOut);

                                if (ack == Ack)
                                {
                                    resultStream.WriteByte(ack);
                                    byte[] responseData = null;
                                    if (sourceDataStream != null)
                                    {
                                        SendCommandPayload(target, sourceDataStream, resultStream);
                                    }
                                    else if (inflate != null)
                                    {
                                        responseData = ReceiveResponse(reader, resultStream);
                                    }

                                    var success = GetCommandSuccess(reader);
                                    resultStream.WriteByte(success);

                                    var crc = GetResponseCrc(reader);
                                    succeeded = ValidateResponse(resultStream, crc);

                                    if (succeeded && (responseData != null) && (inflate != null))
                                    {
                                        using (var responseStream = new MemoryStream(responseData))
                                        {
                                            response = inflate(responseStream);
                                        }
                                    }
                                    if (succeeded && (onSuccess != null))
                                    {
                                        onSuccess();
                                    }
                                    if (success != Success)
                                    {
                                        var errorMessage = "Command " + Command + " did not succeed: " + success.ToString("X2") + "(" + System.Convert.ToChar(success) + ")";
                                        if (!string.IsNullOrEmpty(errorDetail))
                                        {
                                            errorDetail += Environment.NewLine;
                                        }
                                        errorDetail += errorMessage;
                                        target.LogPortMessage(errorMessage);
                                        DebugOutput(errorMessage);
                                        timedOut  = target.WaitForBeacon(WaitForBeaconTimeout);    // try to drain any remaining bytes and sync back up again
                                        succeeded = false;
                                        exception = new DeviceCommandExecuteFailedException(Command, Arg0, Arg1, Arg2, Arg3, success);
                                    }
                                }
                                else if (ack == Nak)
                                {
                                    var errorMessage = "Command " + Command + " returned NAK!";
                                    target.LogPortMessage(errorMessage);
                                    DebugOutput(errorMessage);
                                    timedOut = !target.WaitForBeacon(WaitForBeaconTimeout);
                                    if (!string.IsNullOrEmpty(errorDetail))
                                    {
                                        errorDetail += Environment.NewLine;
                                    }
                                    errorDetail += errorMessage;
                                }
                            }
                        }
                    }
                    catch (TimeoutException e)
                    {
                        timedOut = true;
                        var errorMessage = "Timed out executing command: " + Command;
                        target.LogPortMessage(errorMessage);
                        DebugOutput(errorMessage);
                        if (!string.IsNullOrEmpty(errorDetail))
                        {
                            errorDetail += Environment.NewLine;
                        }
                        errorDetail += errorMessage;
                        exception    = e;

                        // TODO: Report specific failure message back to user.
                    }
                    catch (System.IO.IOException e)
                    {
                        var errorMessage = "IO Exception executing command: " + Command;
                        target.LogPortMessage(errorMessage);
                        DebugOutput(errorMessage);
                        if (!string.IsNullOrEmpty(errorDetail))
                        {
                            errorDetail += Environment.NewLine;
                        }
                        errorDetail += errorMessage;
                        exception    = e;

                        // TODO: Report specific failure message back to user.
                        // One circumstance in which this occurs, and which we do not wish to report, is when killing the simulator application.
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        var errorMessage = "UnauthorizedAccess Exception executing command: " + Command;
                        target.LogPortMessage(errorMessage);
                        DebugOutput(errorMessage);
                        if (!string.IsNullOrEmpty(errorDetail))
                        {
                            errorDetail += Environment.NewLine;
                        }
                        errorDetail += errorMessage;
                        exception    = e;

                        // TODO: Report specific failure message back to user.
                        // One circumstance in which this occurs, was after unplugging the device, which we may not want to report.
                    }
                    finally
                    {
                        // target.WriteStream may go to null if cord is pulled during communication w/ the device.
                        if ((target.WriteStream != null) && target.WriteStream.CanTimeout)
                        {
                            target.WriteStream.WriteTimeout = previousWriteTimeout;
                        }
                        if (!succeeded)
                        {
                            RecordErrorResult(Command, exception, taskData, errorDetail);
                            if (exception != null)
                            {
                                throw exception;
                            }
                        }
                    }
                }
                if (taskData != null)
                {
                    taskData.Succeeded = succeeded;
                }
            }
#if REPORT_COMMAND_PERFORMANCE
        }

        finally
        {
            stopwatch.Stop();
            ReportDuration(stopwatch, reportSuffix, target.Name);
        }
#endif // REPORT_COMMAND_PERFORMANCE
            return(response);
        }
예제 #8
0
        /// <summary>
        /// Sends the command to the specified target and reads the response. The command responds with additional data.
        /// </summary>
        /// <typeparam name="T">The data type of the response data from the command.</typeparam>
        /// <param name="target">The target to which to send the command.</param>
        /// <param name="taskData">If non-<c>null</c>, execution data to update for error reporting.</param>
        /// <param name="inflate">The function to inflate the flat byte array response to response type.</param>
        /// <param name="succeeded">Receives whether the command was sent, and response received, successfully.</param>
        /// <returns>The reply data. If the command fails, this value will be default(T).</returns>
        protected T ExecuteWithResponse <T>(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData, Func <System.IO.Stream, T> inflate, out bool succeeded)
        {
            var response = ExecuteCore(target, taskData, null, inflate, null, out succeeded);

            return(response);
        }
예제 #9
0
 /// <summary>
 /// Sends the command to the specified target.
 /// </summary>
 /// <param name="target">The target to which to send the command.</param>
 /// <param name="taskData">If non-<c>null</c>, execution data to update for error reporting.</param>
 /// <param name="succeeded">Receives whether the command was sent, and response received, successfully.</param>
 /// <returns><c>true</c> if the command and its data were successfully sent, <c>false</c> otherwise.</returns>
 protected bool ExecuteCommand(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData, out bool succeeded)
 {
     succeeded = ExecuteCommandWithData(target, taskData, (System.IO.Stream)null, null);
     return(succeeded);
 }
예제 #10
0
        /// <summary>
        /// Sends the command to the specified target.
        /// </summary>
        /// <param name="target">The target to which to send the command.</param>
        /// <param name="taskData">If non-<c>null</c>, execution data to update for error reporting.</param>
        /// <param name="succeeded">Receives whether the command was sent, and response received, successfully.</param>
        /// <returns>The data returned by the command. In the case of commands that do not send additional results, this will be the same as the succeeded result.</returns>
        public virtual object Execute(IStreamConnection target, ExecuteDeviceCommandAsyncTaskData taskData, out bool succeeded)
        {
            var result = ExecuteCommand(target, taskData, out succeeded);

            return(result);
        }