Files
Aaru/Aaru.Devices/Remote/Remote.cs

1801 lines
60 KiB
C#
Raw Normal View History

2020-03-11 21:56:55 +00:00
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Remote.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Aaru Remote.
//
// --[ Description ] ----------------------------------------------------------
//
// Implementation of 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2020 Natalia Portillo
// ****************************************************************************/
2019-10-12 22:51:50 +01:00
using System;
2019-10-12 23:44:51 +01:00
using System.Collections.Generic;
2019-10-12 22:51:50 +01:00
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
2019-10-12 23:44:51 +01:00
using System.Runtime.InteropServices;
2020-02-27 00:33:26 +00:00
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interop;
using Aaru.Console;
using Aaru.Decoders.ATA;
using Marshal = Aaru.Helpers.Marshal;
using Version = Aaru.CommonTypes.Interop.Version;
2019-10-12 22:51:50 +01:00
2020-02-27 00:33:26 +00:00
namespace Aaru.Devices.Remote
2019-10-12 22:51:50 +01:00
{
2019-10-12 23:12:39 +01:00
public class Remote : IDisposable
2019-10-12 22:51:50 +01:00
{
2020-02-29 18:03:35 +00:00
readonly string _host;
readonly Socket _socket;
2019-10-12 22:51:50 +01:00
public Remote(string host)
{
_host = host;
2019-10-12 22:51:50 +01:00
if(!IPAddress.TryParse(host, out IPAddress ipAddress))
{
IPHostEntry ipHostEntry = Dns.GetHostEntry(host);
ipAddress = ipHostEntry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
}
2020-02-29 18:03:35 +00:00
if(ipAddress is null)
2019-10-12 22:51:50 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Host not found");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new SocketException(11001);
}
var ipEndPoint = new IPEndPoint(ipAddress, 6666);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(ipEndPoint);
2020-02-27 23:48:41 +00:00
AaruConsole.WriteLine("Connected to {0}", host);
2019-10-12 22:51:50 +01:00
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-12 22:51:50 +01:00
2020-02-29 18:03:35 +00:00
int len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-12 22:51:50 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-12 22:51:50 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new IOException();
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-12 22:51:50 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-12 22:51:50 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new ArgumentException();
}
2019-10-13 20:54:10 +01:00
byte[] buf;
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.Hello)
2019-10-12 22:51:50 +01:00
{
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.Nop)
2019-10-13 20:54:10 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected Hello Packet, got packet type {0}...", hdr.packetType);
2020-02-29 18:03:35 +00:00
2019-10-13 20:54:10 +01:00
throw new ArgumentException();
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-13 20:54:10 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-13 20:54:10 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-13 20:54:10 +01:00
throw new IOException();
}
2020-02-29 18:03:35 +00:00
AaruPacketNop nop = Marshal.ByteArrayToStructureLittleEndian<AaruPacketNop>(buf);
2019-10-13 20:54:10 +01:00
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine($"{nop.reason}");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new ArgumentException();
}
2020-07-20 21:11:32 +01:00
if(hdr.version != Consts.PACKET_VERSION)
2019-10-12 22:51:50 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Unrecognized packet version...");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new ArgumentException();
}
2019-10-13 20:54:10 +01:00
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-12 22:51:50 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-12 22:51:50 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new IOException();
}
2020-02-29 18:03:35 +00:00
AaruPacketHello serverHello = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHello>(buf);
2019-10-12 22:51:50 +01:00
2020-02-29 18:03:35 +00:00
ServerApplication = serverHello.application;
ServerVersion = serverHello.version;
ServerOperatingSystem = serverHello.sysname;
2019-10-12 22:51:50 +01:00
ServerOperatingSystemVersion = serverHello.release;
2020-02-29 18:03:35 +00:00
ServerArchitecture = serverHello.machine;
ServerProtocolVersion = serverHello.maxProtocol;
2019-10-12 22:51:50 +01:00
2020-02-27 22:42:21 +00:00
var clientHello = new AaruPacketHello
2019-10-12 22:51:50 +01:00
{
2020-07-20 04:34:16 +01:00
application = "Aaru",
version = Version.GetVersion(),
2020-07-20 21:11:32 +01:00
maxProtocol = Consts.MAX_PROTOCOL,
2020-02-29 18:03:35 +00:00
sysname = DetectOS.GetPlatformName(DetectOS.GetRealPlatformID(), DetectOS.GetVersion()),
2020-07-20 04:34:16 +01:00
release = DetectOS.GetVersion(),
machine = RuntimeInformation.ProcessArchitecture.ToString(),
hdr = new AaruPacketHeader
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketHello>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-07-20 04:34:16 +01:00
packetType = AaruPacketType.Hello
}
2019-10-12 22:51:50 +01:00
};
buf = Marshal.StructureToByteArrayLittleEndian(clientHello);
len = _socket.Send(buf, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len >= buf.Length)
return;
2019-10-12 22:51:50 +01:00
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-12 22:51:50 +01:00
throw new IOException();
}
2020-02-29 18:03:35 +00:00
public string ServerApplication { get; }
public string ServerVersion { get; }
public string ServerOperatingSystem { get; }
2019-10-12 22:51:50 +01:00
public string ServerOperatingSystemVersion { get; }
2020-02-29 18:03:35 +00:00
public string ServerArchitecture { get; }
public int ServerProtocolVersion { get; }
2019-10-12 22:51:50 +01:00
public bool IsRoot
{
get
{
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdAmIRoot
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdAmIRoot>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandAmIRoot
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseAmIRoot)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected Am I Root? Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
return false;
}
buf = new byte[hdr.len];
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketResAmIRoot res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResAmIRoot>(buf);
return res.am_i_root != 0;
}
}
2020-02-29 18:03:35 +00:00
public void Dispose() => Disconnect();
2019-10-12 23:12:39 +01:00
2019-10-12 22:51:50 +01:00
public void Disconnect()
{
try
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch(ObjectDisposedException)
{
// Ignore if already disposed
}
2019-10-12 22:51:50 +01:00
}
2019-10-12 23:12:39 +01:00
public DeviceInfo[] ListDevices()
{
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCommandListDevices
2019-10-12 23:23:33 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-12 23:23:33 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCommandListDevices>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandListDevices
2019-10-12 23:23:33 +01:00
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2019-10-12 23:23:33 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-12 23:23:33 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-12 23:23:33 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2019-10-12 23:23:33 +01:00
return new DeviceInfo[0];
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-12 23:44:51 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-12 23:44:51 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-12 23:44:51 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-12 23:44:51 +01:00
return new DeviceInfo[0];
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-12 23:44:51 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-12 23:44:51 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-12 23:44:51 +01:00
return new DeviceInfo[0];
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseListDevices)
2019-10-12 23:44:51 +01:00
{
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.Nop)
2019-10-13 20:54:10 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected List Devices Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
2019-10-13 20:54:10 +01:00
return new DeviceInfo[0];
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-13 20:54:10 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-13 20:54:10 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-13 20:54:10 +01:00
return new DeviceInfo[0];
}
2020-02-29 18:03:35 +00:00
AaruPacketNop nop = Marshal.ByteArrayToStructureLittleEndian<AaruPacketNop>(buf);
2019-10-13 20:54:10 +01:00
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine($"{nop.reason}");
2020-02-29 18:03:35 +00:00
2019-10-12 23:44:51 +01:00
return new DeviceInfo[0];
}
2020-07-20 21:11:32 +01:00
if(hdr.version != Consts.PACKET_VERSION)
2019-10-12 23:44:51 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Unrecognized packet version...");
2020-02-29 18:03:35 +00:00
2019-10-12 23:44:51 +01:00
return new DeviceInfo[0];
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-12 23:44:51 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-12 23:44:51 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-12 23:44:51 +01:00
return new DeviceInfo[0];
}
2020-02-29 18:03:35 +00:00
AaruPacketResponseListDevices response =
Marshal.ByteArrayToStructureLittleEndian<AaruPacketResponseListDevices>(buf);
List<DeviceInfo> devices = new List<DeviceInfo>();
int offset = Marshal.SizeOf<AaruPacketResponseListDevices>();
int devInfoLen = Marshal.SizeOf<DeviceInfo>();
2019-10-12 23:44:51 +01:00
2020-02-29 18:03:35 +00:00
for(ushort i = 0; i < response.devices; i++)
2019-10-12 23:44:51 +01:00
{
2020-02-29 18:03:35 +00:00
DeviceInfo dev = Marshal.ByteArrayToStructureLittleEndian<DeviceInfo>(buf, offset, devInfoLen);
2020-03-01 06:02:40 +00:00
dev.Path = dev.Path[0] == '/' ? $"aaru://{_host}{dev.Path}" : $"aaru://{_host}/{dev.Path}";
devices.Add(dev);
2019-10-12 23:44:51 +01:00
offset += devInfoLen;
}
return devices.ToArray();
2019-10-12 23:12:39 +01:00
}
2019-10-13 22:29:09 +01:00
2019-10-19 18:28:05 +01:00
public bool Open(string devicePath, out int lastError)
2019-10-13 22:29:09 +01:00
{
2019-10-19 18:28:05 +01:00
lastError = 0;
2019-10-13 22:29:09 +01:00
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCommandOpenDevice
2019-10-13 22:29:09 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-13 22:29:09 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCommandOpenDevice>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandOpen
2019-10-13 22:29:09 +01:00
},
device_path = devicePath
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2019-10-13 22:29:09 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-13 22:29:09 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-13 22:29:09 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2019-10-19 18:28:05 +01:00
lastError = -1;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-13 22:29:09 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-13 22:29:09 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-13 22:29:09 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2019-10-19 18:28:05 +01:00
lastError = -1;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-13 22:29:09 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-13 22:29:09 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2019-10-19 18:28:05 +01:00
lastError = -1;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.Nop)
2019-10-13 22:29:09 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected List Devices Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
2019-10-19 18:28:05 +01:00
lastError = -1;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-13 22:29:09 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-13 22:29:09 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2019-10-19 18:28:05 +01:00
lastError = -1;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketNop nop = Marshal.ByteArrayToStructureLittleEndian<AaruPacketNop>(buf);
2019-10-13 22:29:09 +01:00
2020-02-29 18:03:35 +00:00
switch(nop.reasonCode)
2019-10-13 22:29:09 +01:00
{
2020-02-29 18:03:35 +00:00
case AaruNopReason.OpenOk: return true;
case AaruNopReason.NotImplemented: throw new NotImplementedException($"{nop.reason}");
2019-10-13 22:29:09 +01:00
}
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine($"{nop.reason}");
2019-10-19 18:28:05 +01:00
lastError = nop.errno;
2020-02-29 18:03:35 +00:00
2019-10-13 22:29:09 +01:00
return false;
}
2019-10-13 23:31:56 +01:00
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
2020-02-29 18:03:35 +00:00
ScsiDirection direction, out double duration, out bool sense)
2019-10-13 23:31:56 +01:00
{
2019-10-17 22:15:01 +01:00
senseBuffer = null;
2020-02-29 18:03:35 +00:00
duration = 0;
sense = true;
2019-10-17 22:15:01 +01:00
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdScsi
2019-10-17 22:15:01 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-17 22:15:01 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandScsi
2019-10-17 22:15:01 +01:00
},
2020-07-20 04:34:16 +01:00
direction = (int)direction,
timeout = timeout * 1000
2019-10-17 22:15:01 +01:00
};
2020-02-29 18:03:35 +00:00
if(cdb != null)
cmdPkt.cdb_len = (uint)cdb.Length;
if(buffer != null)
cmdPkt.buf_len = (uint)buffer.Length;
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdScsi>() + cmdPkt.cdb_len + cmdPkt.buf_len);
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
byte[] buf = new byte[cmdPkt.hdr.len];
2019-10-17 22:15:01 +01:00
2020-02-27 22:42:21 +00:00
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdScsi>());
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
if(cdb != null)
2020-02-27 22:42:21 +00:00
Array.Copy(cdb, 0, buf, Marshal.SizeOf<AaruPacketCmdScsi>(), cmdPkt.cdb_len);
2020-02-29 18:03:35 +00:00
if(buffer != null)
2020-02-27 22:42:21 +00:00
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdScsi>() + cmdPkt.cdb_len, cmdPkt.buf_len);
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-17 22:15:01 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-17 22:15:01 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-17 22:15:01 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-17 22:15:01 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-17 22:15:01 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-17 22:15:01 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-17 22:15:01 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-17 22:15:01 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseScsi)
2019-10-17 22:15:01 +01:00
{
2020-02-29 18:03:35 +00:00
AaruConsole.ErrorWriteLine("Expected SCSI Response Packet, got packet type {0}...", hdr.packetType);
2019-10-17 22:15:01 +01:00
return -1;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-17 22:15:01 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-17 22:15:01 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketResScsi res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResScsi>(buf);
2019-10-17 22:15:01 +01:00
senseBuffer = new byte[res.sense_len];
2020-02-27 22:42:21 +00:00
Array.Copy(buf, Marshal.SizeOf<AaruPacketResScsi>(), senseBuffer, 0, res.sense_len);
2019-10-17 22:15:01 +01:00
buffer = new byte[res.buf_len];
2020-02-27 22:42:21 +00:00
Array.Copy(buf, Marshal.SizeOf<AaruPacketResScsi>() + res.sense_len, buffer, 0, res.buf_len);
2019-10-17 22:15:01 +01:00
duration = res.duration;
2020-02-29 18:03:35 +00:00
sense = res.sense != 0;
2019-10-17 22:15:01 +01:00
2020-02-29 18:03:35 +00:00
return (int)res.error_no;
2019-10-13 23:31:56 +01:00
}
public int SendAtaCommand(AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
2020-02-29 18:03:35 +00:00
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, bool transferBlocks, out double duration, out bool sense)
2019-10-13 23:31:56 +01:00
{
2020-02-29 18:03:35 +00:00
duration = 0;
sense = true;
2019-10-19 03:11:27 +01:00
errorRegisters = new AtaErrorRegistersChs();
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdAtaChs
2019-10-19 03:11:27 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-19 03:11:27 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandAtaChs
2019-10-19 03:11:27 +01:00
},
2020-07-20 04:34:16 +01:00
registers = registers,
protocol = (byte)protocol,
transferRegister = (byte)transferRegister,
transferBlocks = transferBlocks,
timeout = timeout * 1000
2019-10-19 03:11:27 +01:00
};
2020-02-29 18:03:35 +00:00
if(buffer != null)
cmdPkt.buf_len = (uint)buffer.Length;
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdAtaChs>() + cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
byte[] buf = new byte[cmdPkt.hdr.len];
2019-10-19 03:11:27 +01:00
2020-02-27 22:42:21 +00:00
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdAtaChs>());
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(buffer != null)
2020-02-27 22:42:21 +00:00
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdAtaChs>(), cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-19 03:11:27 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-19 03:11:27 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-19 03:11:27 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseAtaChs)
2019-10-19 03:11:27 +01:00
{
2020-02-29 18:03:35 +00:00
AaruConsole.ErrorWriteLine("Expected ATA CHS Response Packet, got packet type {0}...", hdr.packetType);
2019-10-19 03:11:27 +01:00
return -1;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketResAtaChs res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResAtaChs>(buf);
2019-10-19 03:11:27 +01:00
buffer = new byte[res.buf_len];
2020-02-27 22:42:21 +00:00
Array.Copy(buf, Marshal.SizeOf<AaruPacketResAtaChs>(), buffer, 0, res.buf_len);
2020-02-29 18:03:35 +00:00
duration = res.duration;
sense = res.sense != 0;
2019-10-19 03:11:27 +01:00
errorRegisters = res.registers;
2020-02-29 18:03:35 +00:00
return (int)res.error_no;
2019-10-13 23:31:56 +01:00
}
public int SendAtaCommand(AtaRegistersLba28 registers, out AtaErrorRegistersLba28 errorRegisters,
2020-02-29 18:03:35 +00:00
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, bool transferBlocks, out double duration, out bool sense)
2019-10-13 23:31:56 +01:00
{
2020-02-29 18:03:35 +00:00
duration = 0;
sense = true;
2019-10-19 03:11:27 +01:00
errorRegisters = new AtaErrorRegistersLba28();
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdAtaLba28
2019-10-19 03:11:27 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-19 03:11:27 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandAtaLba28
2019-10-19 03:11:27 +01:00
},
2020-07-20 04:34:16 +01:00
registers = registers,
protocol = (byte)protocol,
transferRegister = (byte)transferRegister,
transferBlocks = transferBlocks,
timeout = timeout * 1000
2019-10-19 03:11:27 +01:00
};
2020-02-29 18:03:35 +00:00
if(buffer != null)
cmdPkt.buf_len = (uint)buffer.Length;
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdAtaLba28>() + cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
byte[] buf = new byte[cmdPkt.hdr.len];
2019-10-19 03:11:27 +01:00
2020-02-27 22:42:21 +00:00
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdAtaLba28>());
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(buffer != null)
2020-02-27 22:42:21 +00:00
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdAtaLba28>(), cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-19 03:11:27 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-19 03:11:27 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-19 03:11:27 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseAtaLba28)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected ATA LBA28 Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
2019-10-19 03:11:27 +01:00
return -1;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketResAtaLba28 res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResAtaLba28>(buf);
2019-10-19 03:11:27 +01:00
buffer = new byte[res.buf_len];
2020-02-27 22:42:21 +00:00
Array.Copy(buf, Marshal.SizeOf<AaruPacketResAtaLba28>(), buffer, 0, res.buf_len);
2020-02-29 18:03:35 +00:00
duration = res.duration;
sense = res.sense != 0;
2019-10-19 03:11:27 +01:00
errorRegisters = res.registers;
2020-02-29 18:03:35 +00:00
return (int)res.error_no;
2019-10-13 23:31:56 +01:00
}
public int SendAtaCommand(AtaRegistersLba48 registers, out AtaErrorRegistersLba48 errorRegisters,
2020-02-29 18:03:35 +00:00
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, bool transferBlocks, out double duration, out bool sense)
2019-10-13 23:31:56 +01:00
{
2020-02-29 18:03:35 +00:00
duration = 0;
sense = true;
2019-10-19 03:11:27 +01:00
errorRegisters = new AtaErrorRegistersLba48();
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdAtaLba48
2019-10-19 03:11:27 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-19 03:11:27 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandAtaLba48
2019-10-19 03:11:27 +01:00
},
2020-07-20 04:34:16 +01:00
registers = registers,
protocol = (byte)protocol,
transferRegister = (byte)transferRegister,
transferBlocks = transferBlocks,
timeout = timeout * 1000
2019-10-19 03:11:27 +01:00
};
2020-02-29 18:03:35 +00:00
if(buffer != null)
cmdPkt.buf_len = (uint)buffer.Length;
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdAtaLba48>() + cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
byte[] buf = new byte[cmdPkt.hdr.len];
2019-10-19 03:11:27 +01:00
2020-02-27 22:42:21 +00:00
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdAtaLba48>());
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(buffer != null)
2020-02-27 22:42:21 +00:00
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdAtaLba48>(), cmdPkt.buf_len);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-19 03:11:27 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-19 03:11:27 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-19 03:11:27 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseAtaLba48)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected ATA LBA48 Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
2019-10-19 03:11:27 +01:00
return -1;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-19 03:11:27 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-19 03:11:27 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 03:11:27 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketResAtaLba48 res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResAtaLba48>(buf);
2019-10-19 03:11:27 +01:00
buffer = new byte[res.buf_len];
2020-02-27 22:42:21 +00:00
Array.Copy(buf, Marshal.SizeOf<AaruPacketResAtaLba48>(), buffer, 0, res.buf_len);
2020-02-29 18:03:35 +00:00
duration = res.duration;
sense = res.sense != 0;
2019-10-19 03:11:27 +01:00
errorRegisters = res.registers;
2020-02-29 18:03:35 +00:00
return (int)res.error_no;
2019-10-13 23:31:56 +01:00
}
2020-02-29 18:03:35 +00:00
public int SendMmcCommand(MmcCommands command, bool write, bool isApplication, MmcFlags flags, uint argument,
uint blockSize, uint blocks, ref byte[] buffer, out uint[] response,
out double duration, out bool sense, uint timeout = 0)
2019-10-13 23:31:56 +01:00
{
2019-10-19 17:43:46 +01:00
duration = 0;
2020-02-29 18:03:35 +00:00
sense = true;
2019-10-19 17:43:46 +01:00
response = null;
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdSdhci
2019-10-19 17:43:46 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-19 17:43:46 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
version = Consts.PACKET_VERSION,
packetType = AaruPacketType.CommandSdhci
2019-10-19 17:43:46 +01:00
},
command = new AaruCmdSdhci
{
command = command,
write = write,
application = isApplication,
flags = flags,
argument = argument,
block_size = blockSize,
blocks = blocks,
timeout = timeout * 1000
}
2019-10-19 17:43:46 +01:00
};
2020-02-29 18:03:35 +00:00
if(buffer != null)
cmdPkt.command.buf_len = (uint)buffer.Length;
2019-10-19 17:43:46 +01:00
cmdPkt.hdr.len = (uint)(Marshal.SizeOf<AaruPacketCmdSdhci>() + cmdPkt.command.buf_len);
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
byte[] buf = new byte[cmdPkt.hdr.len];
2019-10-19 17:43:46 +01:00
2020-02-27 22:42:21 +00:00
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdSdhci>());
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
if(buffer != null)
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdSdhci>(), cmdPkt.command.buf_len);
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-19 17:43:46 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 17:43:46 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-19 17:43:46 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-19 17:43:46 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 17:43:46 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-19 17:43:46 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-19 17:43:46 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-19 17:43:46 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseSdhci)
2019-10-19 17:43:46 +01:00
{
2020-02-29 18:03:35 +00:00
AaruConsole.ErrorWriteLine("Expected SDHCI Response Packet, got packet type {0}...", hdr.packetType);
2019-10-19 17:43:46 +01:00
return -1;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-19 17:43:46 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-19 17:43:46 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-19 17:43:46 +01:00
return -1;
}
2020-02-29 18:03:35 +00:00
AaruPacketResSdhci res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResSdhci>(buf);
2019-10-19 17:43:46 +01:00
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;
2020-02-29 18:03:35 +00:00
response = new uint[4];
response[0] = res.res.response[0];
response[1] = res.res.response[1];
response[2] = res.res.response[2];
response[3] = res.res.response[3];
2019-10-19 17:43:46 +01:00
return (int)res.res.error_no;
2019-10-13 23:31:56 +01:00
}
2019-10-14 01:02:25 +01:00
public DeviceType GetDeviceType()
{
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdGetDeviceType
2019-10-16 20:07:24 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-16 20:07:24 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdGetDeviceType>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandGetType
2019-10-16 20:07:24 +01:00
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2019-10-16 20:07:24 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-16 20:07:24 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-16 20:07:24 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-16 20:07:24 +01:00
return DeviceType.Unknown;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-16 20:07:24 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-16 20:07:24 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-16 20:07:24 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-16 20:07:24 +01:00
return DeviceType.Unknown;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-16 20:07:24 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-16 20:07:24 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-16 20:07:24 +01:00
return DeviceType.Unknown;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseGetType)
2019-10-16 20:07:24 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected Device Type Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
2019-10-16 20:07:24 +01:00
return DeviceType.Unknown;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-16 20:07:24 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-16 20:07:24 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-16 20:07:24 +01:00
return DeviceType.Unknown;
}
2020-02-29 18:03:35 +00:00
AaruPacketResGetDeviceType res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResGetDeviceType>(buf);
2019-10-16 20:07:24 +01:00
return res.device_type;
2019-10-14 01:02:25 +01:00
}
public bool GetSdhciRegisters(out byte[] csd, out byte[] cid, out byte[] ocr, out byte[] scr)
{
csd = null;
cid = null;
ocr = null;
scr = null;
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdGetSdhciRegisters
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdGetSdhciRegisters>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandGetSdhciRegisters
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseGetSdhciRegisters)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected Device Type Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
return false;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketResGetSdhciRegisters res =
Marshal.ByteArrayToStructureLittleEndian<AaruPacketResGetSdhciRegisters>(buf);
2020-02-29 18:03:35 +00:00
if(res.csd_len > 0)
{
2020-02-29 18:03:35 +00:00
if(res.csd_len > 16)
res.csd_len = 16;
csd = new byte[res.csd_len];
Array.Copy(res.csd, 0, csd, 0, res.csd_len);
}
2020-02-29 18:03:35 +00:00
if(res.cid_len > 0)
{
2020-02-29 18:03:35 +00:00
if(res.cid_len > 16)
res.cid_len = 16;
cid = new byte[res.cid_len];
Array.Copy(res.cid, 0, cid, 0, res.cid_len);
}
2020-02-29 18:03:35 +00:00
if(res.ocr_len > 0)
{
2020-02-29 18:03:35 +00:00
if(res.ocr_len > 16)
res.ocr_len = 16;
ocr = new byte[res.ocr_len];
Array.Copy(res.ocr, 0, ocr, 0, res.ocr_len);
}
2020-02-29 18:03:35 +00:00
if(res.scr_len > 0)
{
2020-02-29 18:03:35 +00:00
if(res.scr_len > 16)
res.scr_len = 16;
scr = new byte[res.scr_len];
Array.Copy(res.scr, 0, scr, 0, res.scr_len);
}
return res.isSdhci;
}
public bool GetUsbData(out byte[] descriptors, out ushort idVendor, out ushort idProduct,
2020-02-29 18:03:35 +00:00
out string manufacturer, out string product, out string serial)
{
2020-02-29 18:03:35 +00:00
descriptors = null;
idVendor = 0;
idProduct = 0;
2019-10-18 23:42:18 +01:00
manufacturer = null;
2020-02-29 18:03:35 +00:00
product = null;
serial = null;
2019-10-18 23:42:18 +01:00
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdGetUsbData
2019-10-18 23:42:18 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-18 23:42:18 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdGetUsbData>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandGetUsbData
2019-10-18 23:42:18 +01:00
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2019-10-18 23:42:18 +01:00
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2019-10-18 23:42:18 +01:00
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
2019-10-18 23:42:18 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
2019-10-18 23:42:18 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-18 23:42:18 +01:00
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2019-10-18 23:42:18 +01:00
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
2019-10-18 23:42:18 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-18 23:42:18 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2019-10-18 23:42:18 +01:00
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
2019-10-18 23:42:18 +01:00
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
2019-10-18 23:42:18 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseGetUsbData)
2019-10-18 23:42:18 +01:00
{
2020-02-29 18:03:35 +00:00
AaruConsole.ErrorWriteLine("Expected USB Data Response Packet, got packet type {0}...", hdr.packetType);
2019-10-18 23:42:18 +01:00
return false;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2019-10-18 23:42:18 +01:00
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
2019-10-18 23:42:18 +01:00
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
2019-10-18 23:42:18 +01:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketResGetUsbData res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResGetUsbData>(buf);
2019-10-18 23:42:18 +01:00
2020-02-29 18:03:35 +00:00
if(!res.isUsb)
2019-10-18 23:42:18 +01:00
return false;
descriptors = new byte[res.descLen];
Array.Copy(res.descriptors, 0, descriptors, 0, res.descLen);
2020-02-29 18:03:35 +00:00
idVendor = res.idVendor;
idProduct = res.idProduct;
2019-10-18 23:42:18 +01:00
manufacturer = res.manufacturer;
2020-02-29 18:03:35 +00:00
product = res.product;
serial = res.serial;
2019-10-18 23:42:18 +01:00
return true;
}
2020-02-29 18:03:35 +00:00
public bool GetFireWireData(out uint idVendor, out uint idProduct, out ulong guid, out string vendor,
out string model)
{
2020-02-29 18:03:35 +00:00
idVendor = 0;
idProduct = 0;
2020-02-29 18:03:35 +00:00
guid = 0;
vendor = null;
model = null;
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdGetFireWireData
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdGetFireWireData>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandGetFireWireData
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseGetFireWireData)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected FireWire Data Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
return false;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketResGetFireWireData res =
Marshal.ByteArrayToStructureLittleEndian<AaruPacketResGetFireWireData>(buf);
2020-02-29 18:03:35 +00:00
if(!res.isFireWire)
return false;
2020-02-29 18:03:35 +00:00
idVendor = res.idVendor;
idProduct = res.idModel;
2020-02-29 18:03:35 +00:00
guid = res.guid;
vendor = res.vendor;
model = res.model;
return true;
}
public bool GetPcmciaData(out byte[] cis)
{
cis = null;
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdGetPcmciaData
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdGetPcmciaData>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandGetPcmciaData
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2020-02-29 18:03:35 +00:00
int len = _socket.Send(buf, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len != buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not write to the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
byte[] hdrBuf = new byte[Marshal.SizeOf<AaruPacketHeader>()];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);
2020-02-29 18:03:35 +00:00
if(len < hdrBuf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian<AaruPacketHeader>(hdrBuf);
2020-07-20 21:11:32 +01:00
if(hdr.remote_id != Consts.REMOTE_ID ||
hdr.packet_id != Consts.PACKET_ID)
{
2020-02-28 00:19:50 +00:00
AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
if(hdr.packetType != AaruPacketType.ResponseGetPcmciaData)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Expected PCMCIA Data Response Packet, got packet type {0}...",
2020-02-29 18:03:35 +00:00
hdr.packetType);
return false;
}
buf = new byte[hdr.len];
2019-10-21 19:05:19 +01:00
len = Receive(_socket, buf, buf.Length, SocketFlags.None);
2020-02-29 18:03:35 +00:00
if(len < buf.Length)
{
2020-02-27 23:48:41 +00:00
AaruConsole.ErrorWriteLine("Could not read from the network...");
2020-02-29 18:03:35 +00:00
return false;
}
2020-02-29 18:03:35 +00:00
AaruPacketResGetPcmciaData res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResGetPcmciaData>(buf);
2020-02-29 18:03:35 +00:00
if(!res.isPcmcia)
return false;
cis = res.cis;
return true;
}
2019-10-21 19:05:19 +01:00
2020-02-29 18:03:35 +00:00
static int Receive(Socket socket, byte[] buffer, int size, SocketFlags socketFlags)
2019-10-21 19:05:19 +01:00
{
2020-02-29 18:03:35 +00:00
int offset = 0;
2019-10-21 19:05:19 +01:00
2020-02-29 18:03:35 +00:00
while(size > 0)
2019-10-21 19:05:19 +01:00
{
int got = socket.Receive(buffer, offset, size, socketFlags);
2019-10-21 19:05:19 +01:00
if(got <= 0)
2020-02-29 18:03:35 +00:00
break;
2019-10-21 19:05:19 +01:00
offset += got;
size -= got;
2019-10-21 19:05:19 +01:00
}
return offset;
}
2019-10-26 15:47:36 +01:00
public void Close()
{
2020-02-27 22:42:21 +00:00
var cmdPkt = new AaruPacketCmdClose
2019-10-26 15:47:36 +01:00
{
2020-02-27 22:42:21 +00:00
hdr = new AaruPacketHeader
2019-10-26 15:47:36 +01:00
{
2020-07-20 21:11:32 +01:00
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
2020-07-20 04:34:16 +01:00
len = (uint)Marshal.SizeOf<AaruPacketCmdClose>(),
2020-07-20 21:11:32 +01:00
version = Consts.PACKET_VERSION,
2020-02-27 22:42:21 +00:00
packetType = AaruPacketType.CommandCloseDevice
2019-10-26 15:47:36 +01:00
}
};
2020-02-29 18:03:35 +00:00
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
2019-10-26 15:47:36 +01:00
try
{
_socket.Send(buf, SocketFlags.None);
}
catch(ObjectDisposedException)
{
// Ignore if already disposed
}
2019-10-26 15:47:36 +01:00
}
public int SendMultipleMmcCommands(Device.MmcSingleCommand[] commands, out double duration, out bool sense,
uint timeout = 0)
{
if(ServerProtocolVersion < 2)
return SendMultipleMmcCommandsV1(commands, out duration, out sense, timeout);
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)
{
sense = false;
duration = 0;
int error = 0;
foreach(Device.MmcSingleCommand command in commands)
{
error = SendMmcCommand(command.command, command.write, command.isApplication, command.flags,
command.argument, command.blockSize, command.blocks, ref command.buffer,
out command.response, out double cmdDuration, out bool cmdSense, timeout);
if(cmdSense)
sense = true;
duration += cmdDuration;
}
return error;
}
public bool ReOpen()
{
var cmdPkt = new AaruPacketCmdReOpen
{
hdr = new AaruPacketHeader
{
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
len = (uint)Marshal.SizeOf<AaruPacketCmdReOpen>(),
version = Consts.PACKET_VERSION,
packetType = AaruPacketType.CommandReOpenDevice
}
};
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
int len = _socket.Send(buf, SocketFlags.None);
if(len != buf.Length)
{
AaruConsole.ErrorWriteLine("Could not write to the network...");
return false;
}
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 false;
}
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 false;
}
if(hdr.packetType != AaruPacketType.Nop)
{
AaruConsole.ErrorWriteLine("Expected NOP Packet, got packet type {0}...", hdr.packetType);
return false;
}
if(hdr.version != Consts.PACKET_VERSION)
{
AaruConsole.ErrorWriteLine("Unrecognized packet version...");
return false;
}
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 false;
}
AaruPacketNop nop = Marshal.ByteArrayToStructureLittleEndian<AaruPacketNop>(buf);
switch(nop.reasonCode)
{
case AaruNopReason.ReOpenOk: return true;
case AaruNopReason.CloseError:
case AaruNopReason.OpenError:
AaruConsole.ErrorWriteLine("ReOpen error closing device...");
break;
default:
AaruConsole.ErrorWriteLine("ReOpen error {0} with reason: {1}...", nop.errno, nop.reason);
break;
}
return false;
}
public bool BufferedOsRead(out byte[] buffer, long offset, uint length, out double duration)
{
duration = 0;
buffer = null;
var cmdPkt = new AaruPacketCmdOsRead
{
hdr = new AaruPacketHeader
{
remote_id = Consts.REMOTE_ID,
packet_id = Consts.PACKET_ID,
len = (uint)Marshal.SizeOf<AaruPacketCmdOsRead>(),
version = Consts.PACKET_VERSION,
packetType = AaruPacketType.CommandOsRead
},
length = length,
offset = (ulong)offset
};
byte[] buf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
int len = _socket.Send(buf, SocketFlags.None);
if(len != buf.Length)
{
AaruConsole.ErrorWriteLine("Could not write to the network...");
return false;
}
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 false;
}
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 false;
}
if(hdr.packetType != AaruPacketType.ResponseOsRead)
{
AaruConsole.ErrorWriteLine("Expected OS Read Response Packet, got packet type {0}...", hdr.packetType);
return false;
}
if(hdr.version != Consts.PACKET_VERSION)
{
AaruConsole.ErrorWriteLine("Unrecognized packet version...");
return false;
}
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 false;
}
AaruPacketResOsRead osRead = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResOsRead>(buf);
duration = osRead.duration;
if(osRead.errno != 0)
{
AaruConsole.ErrorWriteLine("Remote error {0} in OS Read...", osRead.errno);
return false;
}
buffer = new byte[length];
Array.Copy(buf, Marshal.SizeOf<AaruPacketResOsRead>(), buffer, 0, length);
return true;
}
2019-10-12 22:51:50 +01:00
}
}