Skip to content
Permalink
Browse files
Merge pull request #6164 from leoetlino/usb-hid
IOS/USB: Implement HIDv5
  • Loading branch information
leoetlino committed Nov 19, 2017
2 parents b8c83dd + 18a947a commit a755467
Show file tree
Hide file tree
Showing 11 changed files with 597 additions and 416 deletions.
@@ -7,6 +7,7 @@
#include <algorithm>
#include <map>

#include "Common/Assert.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "Core/HW/Memmap.h"
@@ -77,6 +78,14 @@ IOCtlVRequest::IOCtlVRequest(const u32 address_) : Request(address_)
}
}

const IOCtlVRequest::IOVector* IOCtlVRequest::GetVector(size_t index) const
{
_assert_(index < (in_vectors.size() + io_vectors.size()));
if (index < in_vectors.size())
return &in_vectors[index];
return &io_vectors[index - in_vectors.size()];
}

bool IOCtlVRequest::HasNumberOfValidVectors(const size_t in_count, const size_t io_count) const
{
if (in_vectors.size() != in_count || io_vectors.size() != io_count)
@@ -156,6 +156,7 @@ struct IOCtlVRequest final : Request
// merging them into a single std::vector would make using the first out vector more complicated.
std::vector<IOVector> in_vectors;
std::vector<IOVector> io_vectors;
const IOVector* GetVector(size_t index) const;
explicit IOCtlVRequest(u32 address);
bool HasNumberOfValidVectors(size_t in_count, size_t io_count) const;
void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
@@ -6,7 +6,6 @@

#include <algorithm>

#include "Common/Align.h"
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
@@ -70,82 +69,26 @@ bool Device::HasClass(const u8 device_class) const
});
}

static void CopyToBufferAligned(std::vector<u8>* buffer, const void* data, const size_t size)
void DeviceDescriptor::Swap()
{
buffer->insert(buffer->end(), static_cast<const u8*>(data), static_cast<const u8*>(data) + size);
const size_t number_of_padding_bytes = Common::AlignUp(size, 4) - size;
buffer->insert(buffer->end(), number_of_padding_bytes, 0);
bcdUSB = Common::swap16(bcdUSB);
idVendor = Common::swap16(idVendor);
idProduct = Common::swap16(idProduct);
bcdDevice = Common::swap16(bcdDevice);
}

static void CopyDescriptorToBuffer(std::vector<u8>* buffer, DeviceDescriptor descriptor)
void ConfigDescriptor::Swap()
{
descriptor.bcdUSB = Common::swap16(descriptor.bcdUSB);
descriptor.idVendor = Common::swap16(descriptor.idVendor);
descriptor.idProduct = Common::swap16(descriptor.idProduct);
descriptor.bcdDevice = Common::swap16(descriptor.bcdDevice);
CopyToBufferAligned(buffer, &descriptor, descriptor.bLength);
wTotalLength = Common::swap16(wTotalLength);
}

static void CopyDescriptorToBuffer(std::vector<u8>* buffer, ConfigDescriptor descriptor)
void InterfaceDescriptor::Swap()
{
descriptor.wTotalLength = Common::swap16(descriptor.wTotalLength);
CopyToBufferAligned(buffer, &descriptor, descriptor.bLength);
}

static void CopyDescriptorToBuffer(std::vector<u8>* buffer, InterfaceDescriptor descriptor)
void EndpointDescriptor::Swap()
{
CopyToBufferAligned(buffer, &descriptor, descriptor.bLength);
}

static void CopyDescriptorToBuffer(std::vector<u8>* buffer, EndpointDescriptor descriptor)
{
descriptor.wMaxPacketSize = Common::swap16(descriptor.wMaxPacketSize);
// IOS only copies 8 bytes from the endpoint descriptor, regardless of the actual length
CopyToBufferAligned(buffer, &descriptor, sizeof(descriptor));
}

std::vector<u8> Device::GetDescriptorsUSBV4() const
{
return GetDescriptors([](const auto& descriptor) { return true; });
}

std::vector<u8> Device::GetDescriptorsUSBV5(const u8 interface, const u8 alt_setting) const
{
return GetDescriptors([interface, alt_setting](const auto& descriptor) {
// The USBV5 interfaces present each interface as a different device,
// and the descriptors are filtered by alternate setting.
return descriptor.bInterfaceNumber == interface && descriptor.bAlternateSetting == alt_setting;
});
}

std::vector<u8>
Device::GetDescriptors(std::function<bool(const InterfaceDescriptor&)> predicate) const
{
std::vector<u8> buffer;

const auto device_descriptor = GetDeviceDescriptor();
CopyDescriptorToBuffer(&buffer, device_descriptor);

const auto configurations = GetConfigurations();
for (size_t c = 0; c < configurations.size(); ++c)
{
const auto& config_descriptor = configurations[c];
CopyDescriptorToBuffer(&buffer, config_descriptor);

const auto interfaces = GetInterfaces(static_cast<u8>(c));
for (size_t i = interfaces.size(); i-- > 0;)
{
const auto& descriptor = interfaces[i];
if (!predicate(descriptor))
continue;

CopyDescriptorToBuffer(&buffer, descriptor);
for (const auto& endpoint_descriptor : GetEndpoints(
static_cast<u8>(c), descriptor.bInterfaceNumber, descriptor.bAlternateSetting))
CopyDescriptorToBuffer(&buffer, endpoint_descriptor);
}
}
return buffer;
wMaxPacketSize = Common::swap16(wMaxPacketSize);
}

std::string Device::GetErrorName(const int error_code) const
@@ -44,6 +44,7 @@ constexpr u16 USBHDR(u8 dir, u8 type, u8 recipient, u8 request)

struct DeviceDescriptor
{
void Swap();
u8 bLength;
u8 bDescriptorType;
u16 bcdUSB;
@@ -62,6 +63,7 @@ struct DeviceDescriptor

struct ConfigDescriptor
{
void Swap();
u8 bLength;
u8 bDescriptorType;
u16 wTotalLength;
@@ -74,6 +76,7 @@ struct ConfigDescriptor

struct InterfaceDescriptor
{
void Swap();
u8 bLength;
u8 bDescriptorType;
u8 bInterfaceNumber;
@@ -87,6 +90,7 @@ struct InterfaceDescriptor

struct EndpointDescriptor
{
void Swap();
u8 bLength;
u8 bDescriptorType;
u8 bEndpointAddress;
@@ -158,8 +162,6 @@ class Device
u16 GetVid() const;
u16 GetPid() const;
bool HasClass(u8 device_class) const;
std::vector<u8> GetDescriptorsUSBV4() const;
std::vector<u8> GetDescriptorsUSBV5(u8 interface, u8 alt_setting) const;

virtual DeviceDescriptor GetDeviceDescriptor() const = 0;
virtual std::vector<ConfigDescriptor> GetConfigurations() const = 0;
@@ -178,7 +180,6 @@ class Device
virtual int SubmitTransfer(std::unique_ptr<IsoMessage> message) = 0;

protected:
std::vector<u8> GetDescriptors(std::function<bool(const InterfaceDescriptor&)> predicate) const;
u64 m_id = 0xFFFFFFFFFFFFFFFF;
};
} // namespace USB

0 comments on commit a755467

Please sign in to comment.