/// <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); }
public static void LogPortMessage(this IStreamConnection port, string message) { var portName = "<null>"; if (port != null) { portName = port.Name; port.Log(message); } LogPortMessageToDebugger(message, portName); }
/// <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); }
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); }
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(); }
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(); }
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); }
/// <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); }
/// <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); }
/// <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); }