mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Implement remote command for multiple MMC/SD.
This commit is contained in:
@@ -43,7 +43,7 @@ namespace Aaru.Devices.Remote
|
||||
ResponseGetSdhciRegisters = 18, CommandGetUsbData = 19, ResponseGetUsbData = 20,
|
||||
CommandGetFireWireData = 21, ResponseGetFireWireData = 22, CommandGetPcmciaData = 23,
|
||||
ResponseGetPcmciaData = 24, CommandCloseDevice = 25, CommandAmIRoot = 26,
|
||||
ResponseAmIRoot = 27
|
||||
ResponseAmIRoot = 27, MultiCommandSdhci = 28, ResponseMultiSdhci = 29
|
||||
}
|
||||
|
||||
public enum AaruNopReason : byte
|
||||
|
||||
@@ -870,22 +870,25 @@ namespace Aaru.Devices.Remote
|
||||
remote_id = Consts.REMOTE_ID,
|
||||
packet_id = Consts.PACKET_ID,
|
||||
version = Consts.PACKET_VERSION,
|
||||
packetType = AaruPacketType.CommandAtaLba48
|
||||
packetType = AaruPacketType.CommandSdhci
|
||||
},
|
||||
command = command,
|
||||
write = write,
|
||||
application = isApplication,
|
||||
flags = flags,
|
||||
argument = argument,
|
||||
block_size = blockSize,
|
||||
blocks = blocks,
|
||||
timeout = timeout * 1000
|
||||
command = new AaruCmdSdhci
|
||||
{
|
||||
command = command,
|
||||
write = write,
|
||||
application = isApplication,
|
||||
flags = flags,
|
||||
argument = argument,
|
||||
block_size = blockSize,
|
||||
blocks = blocks,
|
||||
timeout = timeout * 1000
|
||||
}
|
||||
};
|
||||
|
||||
if(buffer != null)
|
||||
cmdPkt.buf_len = (uint)buffer.Length;
|
||||
cmdPkt.command.buf_len = (uint)buffer.Length;
|
||||
|
||||
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdSdhci>() + cmdPkt.buf_len);
|
||||
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdSdhci>() + cmdPkt.command.buf_len);
|
||||
|
||||
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
|
||||
byte[] buf = new byte[cmdPkt.hdr.len];
|
||||
@@ -893,7 +896,7 @@ namespace Aaru.Devices.Remote
|
||||
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdSdhci>());
|
||||
|
||||
if(buffer != null)
|
||||
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdSdhci>(), cmdPkt.buf_len);
|
||||
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdSdhci>(), cmdPkt.command.buf_len);
|
||||
|
||||
int len = _socket.Send(buf, SocketFlags.None);
|
||||
|
||||
@@ -944,17 +947,17 @@ namespace Aaru.Devices.Remote
|
||||
|
||||
AaruPacketResSdhci res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResSdhci>(buf);
|
||||
|
||||
buffer = new byte[res.buf_len];
|
||||
Array.Copy(buf, Marshal.SizeOf<AaruPacketResSdhci>(), buffer, 0, res.buf_len);
|
||||
duration = res.duration;
|
||||
sense = res.sense != 0;
|
||||
buffer = new byte[res.res.buf_len];
|
||||
Array.Copy(buf, Marshal.SizeOf<AaruPacketResSdhci>(), buffer, 0, res.res.buf_len);
|
||||
duration = res.res.duration;
|
||||
sense = res.res.sense != 0;
|
||||
response = new uint[4];
|
||||
response[0] = res.response[0];
|
||||
response[1] = res.response[1];
|
||||
response[2] = res.response[2];
|
||||
response[3] = res.response[3];
|
||||
response[0] = res.res.response[0];
|
||||
response[1] = res.res.response[1];
|
||||
response[2] = res.res.response[2];
|
||||
response[3] = res.res.response[3];
|
||||
|
||||
return (int)res.error_no;
|
||||
return (int)res.res.error_no;
|
||||
}
|
||||
|
||||
public DeviceType GetDeviceType()
|
||||
@@ -1440,11 +1443,160 @@ namespace Aaru.Devices.Remote
|
||||
if(ServerProtocolVersion < 2)
|
||||
return SendMultipleMmcCommandsV1(commands, out duration, out sense, timeout);
|
||||
|
||||
throw new NotImplementedException();
|
||||
sense = false;
|
||||
duration = 0;
|
||||
|
||||
long packetSize = Marshal.SizeOf<AaruPacketMultiCmdSdhci>() +
|
||||
(Marshal.SizeOf<AaruCmdSdhci>() * commands.LongLength);
|
||||
|
||||
foreach(Device.MmcSingleCommand command in commands)
|
||||
packetSize += command.buffer?.Length ?? 0;
|
||||
|
||||
var packet = new AaruPacketMultiCmdSdhci
|
||||
{
|
||||
cmd_count = (ulong)commands.LongLength,
|
||||
hdr = new AaruPacketHeader
|
||||
{
|
||||
len = (uint)packetSize,
|
||||
packetType = AaruPacketType.MultiCommandSdhci,
|
||||
remote_id = Consts.REMOTE_ID,
|
||||
packet_id = Consts.PACKET_ID,
|
||||
version = Consts.PACKET_VERSION
|
||||
}
|
||||
};
|
||||
|
||||
byte[] buf = new byte[packetSize];
|
||||
byte[] tmp = Marshal.StructureToByteArrayLittleEndian(packet);
|
||||
|
||||
Array.Copy(tmp, 0, buf, 0, tmp.Length);
|
||||
|
||||
int off = tmp.Length;
|
||||
|
||||
foreach(Device.MmcSingleCommand command in commands)
|
||||
{
|
||||
var cmd = new AaruCmdSdhci
|
||||
{
|
||||
application = command.isApplication,
|
||||
argument = command.argument,
|
||||
block_size = command.blockSize,
|
||||
blocks = command.blocks,
|
||||
buf_len = (uint)(command.buffer?.Length ?? 0),
|
||||
command = command.command,
|
||||
flags = command.flags,
|
||||
timeout = timeout,
|
||||
write = command.write
|
||||
};
|
||||
|
||||
tmp = Marshal.StructureToByteArrayLittleEndian(cmd);
|
||||
Array.Copy(tmp, 0, buf, off, tmp.Length);
|
||||
|
||||
off += tmp.Length;
|
||||
}
|
||||
|
||||
foreach(Device.MmcSingleCommand command in commands)
|
||||
{
|
||||
if((command.buffer?.Length ?? 0) == 0)
|
||||
continue;
|
||||
|
||||
Array.Copy(command.buffer, 0, buf, off, command.buffer.Length);
|
||||
|
||||
off += command.buffer.Length;
|
||||
}
|
||||
|
||||
int len = _socket.Send(buf, SocketFlags.None);
|
||||
|
||||
if(len != buf.Length)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Could not write to the network...");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
|
||||
|
||||
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
|
||||
|
||||
if(len < hdrBuf.Length)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Could not read from the network...");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
|
||||
|
||||
if(hdr.remote_id != Consts.REMOTE_ID ||
|
||||
hdr.packet_id != Consts.PACKET_ID)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(hdr.packetType != AaruPacketType.ResponseMultiSdhci)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Expected multi MMC/SD command Response Packet, got packet type {0}...",
|
||||
hdr.packetType);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = new byte[hdr.len];
|
||||
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
|
||||
|
||||
if(len < buf.Length)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Could not read from the network...");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
AaruPacketMultiCmdSdhci res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketMultiCmdSdhci>(buf);
|
||||
|
||||
if(res.cmd_count != (ulong)commands.Length)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Expected the response to {0} SD/MMC commands, but got {1} responses...",
|
||||
commands.Length, res.cmd_count);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
off = Marshal.SizeOf<AaruPacketMultiCmdSdhci>();
|
||||
|
||||
int error = 0;
|
||||
|
||||
foreach(Device.MmcSingleCommand command in commands)
|
||||
{
|
||||
AaruResSdhci cmdRes =
|
||||
Marshal.ByteArrayToStructureLittleEndian<AaruResSdhci>(buf, off, Marshal.SizeOf<AaruResSdhci>());
|
||||
|
||||
command.response = cmdRes.response;
|
||||
duration += cmdRes.duration;
|
||||
|
||||
if(cmdRes.error_no != 0 &&
|
||||
error == 0)
|
||||
error = (int)cmdRes.error_no;
|
||||
|
||||
if(cmdRes.sense != 0)
|
||||
sense = true;
|
||||
|
||||
if(cmdRes.buf_len > 0)
|
||||
command.buffer = new byte[cmdRes.buf_len];
|
||||
|
||||
off += Marshal.SizeOf<AaruResSdhci>();
|
||||
}
|
||||
|
||||
foreach(Device.MmcSingleCommand command in commands)
|
||||
{
|
||||
Array.Copy(buf, off, command.buffer, 0, command.buffer.Length);
|
||||
off += command.buffer.Length;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int SendMultipleMmcCommandsV1(Device.MmcSingleCommand[] commands, out double duration, out bool sense,
|
||||
uint timeout)
|
||||
uint timeout)
|
||||
{
|
||||
sense = false;
|
||||
duration = 0;
|
||||
|
||||
@@ -210,10 +210,9 @@ namespace Aaru.Devices.Remote
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruPacketCmdSdhci
|
||||
public struct AaruCmdSdhci
|
||||
{
|
||||
public AaruPacketHeader hdr;
|
||||
public MmcCommands command;
|
||||
public MmcCommands command;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool write;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
@@ -227,10 +226,16 @@ namespace Aaru.Devices.Remote
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruPacketResSdhci
|
||||
public struct AaruPacketCmdSdhci
|
||||
{
|
||||
public AaruPacketHeader hdr;
|
||||
public uint buf_len;
|
||||
public AaruCmdSdhci command;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruResSdhci
|
||||
{
|
||||
public uint buf_len;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public uint[] response;
|
||||
@@ -240,6 +245,13 @@ namespace Aaru.Devices.Remote
|
||||
public uint error_no;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruPacketResSdhci
|
||||
{
|
||||
public AaruPacketHeader hdr;
|
||||
public AaruResSdhci res;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruPacketCmdGetDeviceType
|
||||
{
|
||||
@@ -373,4 +385,11 @@ namespace Aaru.Devices.Remote
|
||||
public AaruPacketHeader hdr;
|
||||
public uint am_i_root;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
||||
public struct AaruPacketMultiCmdSdhci
|
||||
{
|
||||
public AaruPacketHeader hdr;
|
||||
public ulong cmd_count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user