private byte[] ReceiveResponse(INTV.Shared.Utility.ASCIIBinaryReader reader, System.IO.MemoryStream resultStream) { var responseData = ReadResponseData(reader); resultStream.Write(responseData, 0, responseData.Length); return(responseData); }
/// <inheritdoc /> protected override byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { byte[] responseData = new byte[ExpectedDataLength]; var bytesRemaining = ExpectedDataLength; var chunkSize = ReadChunkSize == 0 ? ExpectedDataLength : ReadChunkSize; DebugOutput("----------BEGINREAD buffer, expected: " + ExpectedDataLength + ", ChunkSize: " + chunkSize); var chunkNumber = 0; using (var memory = new System.IO.MemoryStream()) { do { var bytesToRead = (bytesRemaining / chunkSize) > 0 ? chunkSize : bytesRemaining; DebugOutput("READING CHUNK # " + chunkNumber++ + ", numToRead: " + bytesToRead); var dataRead = reader.ReadBytes(bytesToRead); DebugOutput("WRITING to memory: " + bytesToRead + ", buff: " + dataRead.Length); memory.Write(dataRead, 0, bytesToRead); bytesRemaining -= bytesToRead; }while (bytesRemaining > 0); memory.Seek(0, System.IO.SeekOrigin.Begin); responseData = memory.ToArray(); } DebugOutput("----------RETURNING buffer: " + responseData.Length + ", expected: " + ExpectedDataLength); return(responseData); }
private static uint Inflate(System.IO.Stream stream) { uint crc = 0; using (var reader = new INTV.Shared.Utility.ASCIIBinaryReader(stream)) { crc = reader.ReadUInt32(); } return(crc); }
/// <summary> /// Creates a new instance of a FileSystem by inflating it from a Stream. /// </summary> /// <param name="stream">The stream containing the data to deserialize to create the object.</param> /// <returns>A new instance of a FileSystem.</returns> public static FileSystem Inflate(System.IO.Stream stream) { FileSystem inflatedObject = null; using (var reader = new INTV.Shared.Utility.ASCIIBinaryReader(stream)) { inflatedObject = Inflate(reader); } return(inflatedObject); }
/// <inheritdoc /> protected override byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { byte[] flattenedData = null; using (var memoryStream = new System.IO.MemoryStream()) { GlobalDirectoryTable.DecompressData(reader, memoryStream); GlobalFileTable.DecompressData(reader, memoryStream); GlobalForkTable.DecompressData(reader, memoryStream); flattenedData = memoryStream.ToArray(); } return(flattenedData); }
private static LfsDirtyFlags Inflate(System.IO.Stream stream) { var dirtyFlags = LfsDirtyFlags.None; using (var reader = new INTV.Shared.Utility.ASCIIBinaryReader(stream)) { var rawFlags = reader.ReadUInt32(); // On a brand new device, these flags come back as all set, so ignore those. if (rawFlags != 0xFFFFFFFF) { dirtyFlags = (LfsDirtyFlags)rawFlags; } } return(dirtyFlags); }
/// <inheritdoc /> protected override byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { return(reader.ReadBytes(ErrorLog.FlatSizeInBytes)); }
/// <inheritdoc /> protected override byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { return(reader.ReadBytes(sizeof(uint))); }
/// <inheritdoc /> protected override byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { return(reader.ReadBytes(FileSystemStatistics.FlatSizeInBytes)); }
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); }
private static uint GetResponseCrc(INTV.Shared.Utility.ASCIIBinaryReader reader) { return(reader.ReadUInt32()); }
private static byte GetCommandSuccess(INTV.Shared.Utility.ASCIIBinaryReader reader) { return(reader.ReadByte()); }
/// <summary> /// Reads the response to a command - ACK, NAK, or other. See remarks. /// </summary> /// <param name="reader">The reader to use to get the response.</param> /// <param name="command">The command that is executing.</param> /// <param name="errorDetail">Receives detailed error information if the command is not acknowledged.</param> /// <param name="timedOut">Receives a value indicating whether or not command execution timed out.</param> /// <returns>The response, which could be Ack, Nak, or possibly another invalid value.</returns> /// <remarks>From Joe's implementation of lc_wait_acknak: /// This function is weird. It must consume some number of partial /// beacons w/out advancing the CRC, and then an ACK/NAK. Only the ACK /// advances the CRC. If we get an unexpected byte, for now just flag /// an error. /// To simplify things, this function does not update the CRC. The /// caller should update the CRC. /// </remarks> private static byte GetCommandAcknowledgement(INTV.Shared.Utility.ASCIIBinaryReader reader, ProtocolCommandId command, ref string errorDetail, out bool timedOut) { byte result = 0xFF; // unknown state timedOut = false; #if false try { do { result = reader.ReadByte(); } while (Device.BeaconCharacters.Contains((char)result)); } catch (TimeoutException) { result = Nak; } #else int state = -1; var prevTimeout = reader.BaseStream.ReadTimeout; if (reader.BaseStream.CanTimeout) { reader.BaseStream.ReadTimeout = 200; } try { const int RetryCount = 6; for (int i = 0; i < RetryCount; ++i) { try { do { timedOut = false; result = reader.ReadByte(); #if DEBUG var forceNak = false; switch (command) { case ProtocolCommandId.Ping: case ProtocolCommandId.GarbageCollect: // never inject a fake NAK for these break; default: forceNak = ReturnNakForNextCommand; break; } if (forceNak) { result = Nak; } #endif // DEBUG if ((result == Ack) || (result == Nak)) { i = RetryCount; var errorMessage = "Command returned NAK directly on port getting command acknowledgement for: " + command + ", not 'virtual' Nak due to garbage."; if (!string.IsNullOrEmpty(errorDetail)) { errorDetail += Environment.NewLine; } errorDetail += errorMessage; DebugOutputIf(result == Nak, errorMessage); break; } if ((state == -1 || state == '\n') && result == 'L') { state = result; } else if ((state == -1 || state == 'L') && result == 'O') { state = result; } else if ((state == -1 || state == 'O') && result == 'C') { state = result; } else if ((state == -1 || state == 'C') && result == 'U') { state = result; } else if ((state == -1 || state == 'U') && result == 'T') { state = result; } else if ((state == -1 || state == 'T') && result == 'U') { state = result; } else if ((state == -1 || state == 'U') && result == 'S') { state = result; } else if ((state == -1 || state == 'S') && result == '\n') { state = result; } else { var errorMessage = "Unexpected response when executing command: " + command + ", returned: " + result; if (!string.IsNullOrEmpty(errorDetail)) { errorDetail += Environment.NewLine; } errorDetail += errorMessage; DebugOutput(errorMessage); state = -1; i = RetryCount; } }while (Device.BeaconCharacters.Contains((char)state)); } catch (TimeoutException) { var errorMessage = "Command response for: " + command + " timed out! Returning 'virtual' Nak"; errorDetail += errorMessage; DebugOutput(errorMessage); timedOut = true; result = Nak; } } } finally { // reader.BaseStream may go bad if cord was pulled during communication. if ((reader.BaseStream != null) && reader.BaseStream.CanTimeout) { reader.BaseStream.ReadTimeout = prevTimeout; } } #endif // false return(result); }
/// <summary> /// If a command expects to receive a response payload, this function must be implemented to read the response data. /// </summary> /// <param name="reader">The binary reader to retrieve the response data.</param> /// <returns>The raw byte stream response returned in response to a command.</returns> protected virtual byte[] ReadResponseData(INTV.Shared.Utility.ASCIIBinaryReader reader) { throw new System.NotImplementedException(); }