Implement remote command for multiple MMC/SD.

This commit is contained in:
2020-12-13 22:04:33 +00:00
parent 6707e95073
commit f2bfe6d9aa
3 changed files with 200 additions and 29 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}
}