// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : Structs.cs // Author(s) : Natalia Portillo // // Component : Aaru Remote. // // --[ Description ] ---------------------------------------------------------- // // Structures for the Aaru Remote protocol. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ using System.Runtime.InteropServices; using Aaru.CommonTypes.Enums; using Aaru.Decoders.ATA; // ReSharper disable MemberCanBeInternal // ReSharper disable MemberCanBePrivate.Global // ReSharper disable FieldCanBeMadeReadOnly.Global // ReSharper disable IdentifierTypo namespace Aaru.Devices.Remote { /// /// Header for any Aaru remote packet /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketHeader { /// /// Unique Aaru packet identifier (primary) /// public uint remote_id; /// /// Unique Aaru packet identifier (secondary) /// public uint packet_id; /// /// Packet length /// public uint len; /// /// Packet version /// public byte version; /// /// Unique Aaru packet type identifier /// public AaruPacketType packetType; /// /// Spare for expansion (or alignment) /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public readonly byte[] spare; } /// /// Hello packet, identifies a remote initiator with a responder /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketHello { /// Packet header public AaruPacketHeader hdr; /// /// Application name /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string application; /// /// Application version /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string version; /// /// Maximum supported protocol version /// public byte maxProtocol; /// /// Spare for expansion (or alignment) /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public readonly byte[] spare; /// /// Operating system name /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string sysname; /// /// Operating system version / release /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string release; /// /// Operating system machine / architecture /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string machine; } /// /// Request a list of device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCommandListDevices { /// Packet header public AaruPacketHeader hdr; } /// /// Returns the requested list of devices /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public readonly struct AaruPacketResponseListDevices { /// Packet header public readonly AaruPacketHeader hdr; /// /// How many device descriptors follows this structure in the packet /// public readonly ushort devices; } /// /// Sends a request or returns a response that requires no intervention or further processing /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketNop { /// Packet header public AaruPacketHeader hdr; /// /// Reason code /// public AaruNopReason reasonCode; /// /// Spare for expansion (or alignment) /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public readonly byte[] spare; /// /// Reason name /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string reason; /// /// Operating system error number /// public int errno; } /// /// Requests to open a device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCommandOpenDevice { /// Packet header public AaruPacketHeader hdr; /// /// Device path /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] public string device_path; } /// /// Requests remote to send a command to a SCSI device. This header is followed by the CDB and after it comes the buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdScsi { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the CDB that follows this structure /// public uint cdb_len; /// /// Length in bytes of the buffer that follows the CDB /// public uint buf_len; /// /// Direction of SCSI data transfer /// public int direction; /// /// Timeout waiting for device to respond to command /// public uint timeout; } /// /// Returns the response from a command sent to a SCSI device. This structure is followed by the buffer containing the REQUEST SENSE response and this is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResScsi { /// Packet header public AaruPacketHeader hdr; /// /// Size the REQUEST SENSE buffer that follows this structure /// public uint sense_len; /// /// Length in bytes of the data buffer that follows the sense buffer /// public uint buf_len; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; /// /// Set to anything different of zero if there was a SENSE returned /// public uint sense; /// /// Set to the remote operating system error number /// public uint error_no; } /// /// Requests remote to send a command to an ATA device using the CHS command set. This header is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaChs { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers to set in the ATA device /// public AtaRegistersChs registers; /// /// ATA protocol code /// public byte protocol; /// /// ATA transfer register indicator /// public byte transferRegister; /// /// Set to true to transfer blocks, false to transfer bytes /// [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// /// Spare for expansion (or alignment) /// public byte spare; /// /// Timeout waiting for device to respond to command /// public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the CHS command set. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaChs { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers as set back by the ATA device /// public AtaErrorRegistersChs registers; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; /// /// Set to anything different of zero if the device set an error condition /// public uint sense; /// /// Set to the remote operating system error number /// public uint error_no; } /// /// Requests remote to send a command to an ATA device using the 28-bit command set. This header is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaLba28 { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers to set in the ATA device /// public AtaRegistersLba28 registers; /// /// ATA protocol code /// public byte protocol; /// /// ATA transfer register indicator /// public byte transferRegister; /// /// Set to true to transfer blocks, false to transfer bytes /// [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// /// Spare for expansion (or alignment) /// public byte spare; /// /// Timeout waiting for device to respond to command /// public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the 28-bit LBA command set. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaLba28 { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers as set back by the ATA device /// public AtaErrorRegistersLba28 registers; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; /// /// Set to anything different of zero if the device set an error condition /// public uint sense; /// /// Set to the remote operating system error number /// public uint error_no; } /// /// Requests remote to send a command to an ATA device using the 48-bit command set. This header is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaLba48 { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers to set in the ATA device /// public AtaRegistersLba48 registers; /// /// ATA protocol code /// public byte protocol; /// /// ATA transfer register indicator /// public byte transferRegister; /// /// Set to true to transfer blocks, false to transfer bytes /// [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// /// Spare for expansion (or alignment) /// public byte spare; /// /// Timeout waiting for device to respond to command /// public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the 48-bit LBA command set. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaLba48 { /// Packet header public AaruPacketHeader hdr; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Registers as set back by the ATA device /// public AtaErrorRegistersLba48 registers; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; /// /// Set to anything different of zero if the device set an error condition /// public uint sense; /// /// Set to the remote operating system error number /// public uint error_no; } /// /// SecureDigital or MultiMediaCard command description /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruCmdSdhci { /// /// Command /// public MmcCommands command; /// /// Set to true if the command writes to the device, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool write; /// /// Set to true if it is an application command, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool application; /// /// Flags /// public MmcFlags flags; /// /// Argument /// public uint argument; /// /// Block size /// public uint block_size; /// /// Number of blocks to transfer /// public uint blocks; /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Timeout waiting for device to respond to command /// public uint timeout; } /// /// Requests remote to send a command to a SecureDigital or MultiMediaCard device attached using a SDHCI controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdSdhci { /// Packet header public AaruPacketHeader hdr; /// /// SecureDigital or MultiMediaCard command description /// public AaruCmdSdhci command; } /// /// Returns the response from a command sent to a SecureDigital or MultiMediaCard device attached to a SDHCI controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruResSdhci { /// /// Length in bytes of the data buffer /// public uint buf_len; /// /// Response registers /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] response; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; /// /// Set to anything different of zero if the device set an error condition /// public uint sense; /// /// Set to the remote operating system error number /// public uint error_no; } /// /// Returns the response from a command sent to a SecureDigital or MultiMediaCard device attached to a SDHCI controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResSdhci { /// Packet header public AaruPacketHeader hdr; /// /// Response /// public AaruResSdhci res; } /// /// Requests the Aaru device type for the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetDeviceType { /// Packet header public AaruPacketHeader hdr; } /// /// Returns the Aaru device type for the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetDeviceType { /// Packet header public AaruPacketHeader hdr; /// /// Aaru's device type /// public DeviceType device_type; } /// /// Requests the registers of a SecureDigital or MultiMediaCard attached to an SDHCI controller /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetSdhciRegisters { /// Packet header public AaruPacketHeader hdr; } /// /// Returns the registers of a SecureDigital or MultiMediaCard attached to an SDHCI controller /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetSdhciRegisters { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached to an SDHCI controller and the rest of the fields on this packet are valid, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isSdhci; /// /// CSD registers /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] csd; /// /// CID registers /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] cid; /// /// OCR registers /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] ocr; /// /// SCR registers /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] scr; /// /// Length of the CSD registers /// public uint csd_len; /// /// Length of the CID registers /// public uint cid_len; /// /// Length of the OCR registers /// public uint ocr_len; /// /// Length of the SCR registers /// public uint scr_len; } /// /// Requests information about the USB connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetUsbData { /// Packet header public AaruPacketHeader hdr; } /// /// Returns information about the USB connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetUsbData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached using USB and the rest of the fields on this packet are valid, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isUsb; /// /// Length of the descriptors /// public ushort descLen; /// /// Raw USB descriptors /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] public byte[] descriptors; /// /// USB vendor ID /// public ushort idVendor; /// /// USB product ID /// public ushort idProduct; /// /// USB manufacturer string /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string manufacturer; /// /// USB product string /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string product; /// /// USB serial number string /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string serial; } /// /// Requests information about the FireWire connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetFireWireData { /// Packet header public AaruPacketHeader hdr; } /// /// Returns information about the FireWire connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetFireWireData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached using FireWire and the rest of the fields on this packet are valid, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isFireWire; /// /// FireWire model ID /// public uint idModel; /// /// FireWire vendor ID /// public uint idVendor; /// /// FireWire's device GUID /// public ulong guid; /// /// FireWire vendor string /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string vendor; /// /// FireWire model string /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string model; } /// /// Requests information about the PCMCIA or CardBus connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetPcmciaData { /// Packet header public AaruPacketHeader hdr; } /// /// Returns information about the PCMCIA or CardBus connection of the opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetPcmciaData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is a PCMCIA or CardBus device and the rest of the fields on this packet are valid, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isPcmcia; /// /// CIS buffer length /// public ushort cis_len; /// /// CIS buffer /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] public byte[] cis; } /// /// Requests to close the currently opened device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdClose { /// Packet header public AaruPacketHeader hdr; } /// /// Requests to know if the remote is running with administrative (aka root) privileges /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAmIRoot { /// Packet header public AaruPacketHeader hdr; } /// /// Returns if the remote is running with administrative (aka root) privileges /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAmIRoot { /// Packet header public AaruPacketHeader hdr; /// /// Set to any value different of 0 to indicate the remote is running with administrative (aka root) privileges /// public uint am_i_root; } /// /// Initiates a multiple command block with the SDHCI controller the SecureDigital or MultiMediaCard is attached /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketMultiCmdSdhci { /// Packet header public AaruPacketHeader hdr; /// /// How many commands to queue /// public ulong cmd_count; } /// /// Closes and then re-opens the same device /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdReOpen { /// Packet header public AaruPacketHeader hdr; } /// /// Reads data using operating system buffers /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdOsRead { /// Packet header public AaruPacketHeader hdr; /// /// Device offset where to read /// public ulong offset; /// /// Number of bytes to read /// public uint length; } /// /// Returns data read using operating system buffers. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResOsRead { /// Packet header public AaruPacketHeader hdr; /// /// Set to the remote operating system error number /// public int errno; /// /// Time in milliseconds it took for the device to execute the command /// public uint duration; } }