2019-10-31 18:00:42 +00:00
|
|
|
#include "SwitchUSBInterface.h"
|
|
|
|
#include "SwitchUSBEndpoint.h"
|
2019-11-04 12:32:43 +00:00
|
|
|
#include <malloc.h>
|
|
|
|
#include <cstring>
|
2019-10-31 18:00:42 +00:00
|
|
|
|
|
|
|
SwitchUSBInterface::SwitchUSBInterface(UsbHsInterface &interface)
|
|
|
|
: m_interface(interface)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SwitchUSBInterface::~SwitchUSBInterface()
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result SwitchUSBInterface::Open()
|
|
|
|
{
|
|
|
|
UsbHsClientIfSession temp;
|
|
|
|
Result rc = usbHsAcquireUsbIf(&temp, &m_interface);
|
|
|
|
if (R_FAILED(rc))
|
2019-11-25 12:58:23 +00:00
|
|
|
return rc;
|
2019-10-31 18:00:42 +00:00
|
|
|
|
|
|
|
m_session = temp;
|
|
|
|
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int i = 0; i != 15; ++i)
|
|
|
|
{
|
2019-11-04 12:32:43 +00:00
|
|
|
usb_endpoint_descriptor &epdesc = m_session.inf.inf.input_endpoint_descs[i];
|
|
|
|
if (epdesc.bLength != 0)
|
|
|
|
{
|
|
|
|
m_inEndpoints[i] = std::make_unique<SwitchUSBEndpoint>(m_session, epdesc);
|
|
|
|
}
|
2019-10-31 18:00:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i != 15; ++i)
|
|
|
|
{
|
2019-11-04 12:32:43 +00:00
|
|
|
usb_endpoint_descriptor &epdesc = m_session.inf.inf.output_endpoint_descs[i];
|
|
|
|
if (epdesc.bLength != 0)
|
|
|
|
{
|
|
|
|
m_outEndpoints[i] = std::make_unique<SwitchUSBEndpoint>(m_session, epdesc);
|
|
|
|
}
|
2019-10-31 18:00:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
void SwitchUSBInterface::Close()
|
|
|
|
{
|
|
|
|
for (auto &&endpoint : m_inEndpoints)
|
|
|
|
{
|
2019-11-04 12:32:43 +00:00
|
|
|
if (endpoint)
|
|
|
|
{
|
|
|
|
endpoint->Close();
|
|
|
|
}
|
2019-10-31 18:00:42 +00:00
|
|
|
}
|
|
|
|
for (auto &&endpoint : m_outEndpoints)
|
|
|
|
{
|
2019-11-04 12:32:43 +00:00
|
|
|
if (endpoint)
|
|
|
|
{
|
|
|
|
endpoint->Close();
|
|
|
|
}
|
2019-10-31 18:00:42 +00:00
|
|
|
}
|
|
|
|
usbHsIfClose(&m_session);
|
|
|
|
}
|
|
|
|
|
2019-11-04 12:32:43 +00:00
|
|
|
Result SwitchUSBInterface::ControlTransfer(u8 bmRequestType, u8 bmRequest, u16 wValue, u16 wIndex, u16 wLength, void *buffer)
|
|
|
|
{
|
2019-11-11 18:23:52 +00:00
|
|
|
void *temp_buffer = memalign(0x1000, wLength);
|
|
|
|
if (temp_buffer == nullptr)
|
2019-11-04 12:32:43 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
u32 transferredSize;
|
|
|
|
|
|
|
|
for (u16 byte = 0; byte != wLength; ++byte)
|
|
|
|
{
|
2019-11-11 18:23:52 +00:00
|
|
|
static_cast<uint8_t *>(temp_buffer)[byte] = static_cast<uint8_t *>(buffer)[byte];
|
2019-11-04 12:32:43 +00:00
|
|
|
}
|
|
|
|
|
2019-11-11 18:23:52 +00:00
|
|
|
Result rc = usbHsIfCtrlXfer(&m_session, bmRequestType, bmRequest, wValue, wIndex, wLength, temp_buffer, &transferredSize);
|
2019-11-04 12:32:43 +00:00
|
|
|
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
|
|
{
|
|
|
|
memset(buffer, 0, wLength);
|
|
|
|
for (u32 byte = 0; byte != transferredSize; ++byte)
|
|
|
|
{
|
2019-11-11 18:23:52 +00:00
|
|
|
static_cast<uint8_t *>(buffer)[byte] = static_cast<uint8_t *>(temp_buffer)[byte];
|
2019-11-04 12:32:43 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-11 18:23:52 +00:00
|
|
|
free(temp_buffer);
|
2019-11-04 12:32:43 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2019-11-21 22:49:51 +00:00
|
|
|
Result SwitchUSBInterface::ControlTransfer(u8 bmRequestType, u8 bmRequest, u16 wValue, u16 wIndex, u16 wLength, const void *buffer)
|
|
|
|
{
|
|
|
|
void *temp_buffer = memalign(0x1000, wLength);
|
|
|
|
if (temp_buffer == nullptr)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
u32 transferredSize;
|
|
|
|
|
|
|
|
for (u16 byte = 0; byte != wLength; ++byte)
|
|
|
|
{
|
|
|
|
static_cast<uint8_t *>(temp_buffer)[byte] = static_cast<const uint8_t *>(buffer)[byte];
|
|
|
|
}
|
|
|
|
|
|
|
|
Result rc = usbHsIfCtrlXfer(&m_session, bmRequestType, bmRequest, wValue, wIndex, wLength, temp_buffer, &transferredSize);
|
|
|
|
free(temp_buffer);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2019-10-31 18:00:42 +00:00
|
|
|
IUSBEndpoint *SwitchUSBInterface::GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index)
|
|
|
|
{
|
|
|
|
if (direction == IUSBEndpoint::USB_ENDPOINT_IN)
|
|
|
|
return m_inEndpoints[index].get();
|
|
|
|
else
|
|
|
|
return m_outEndpoints[index].get();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result SwitchUSBInterface::Reset()
|
|
|
|
{
|
|
|
|
usbHsIfResetDevice(&m_session);
|
|
|
|
return 0;
|
|
|
|
}
|