Merge pull request #4690 from leoetlino/common-usb
IOS: Move out common USB structures
This commit is contained in:
commit
83dc03416e
|
@ -36,6 +36,7 @@ enum LOG_TYPE
|
|||
IOS_SD,
|
||||
IOS_SSL,
|
||||
IOS_STM,
|
||||
IOS_USB,
|
||||
IOS_WC24,
|
||||
IOS_WIIMOTE,
|
||||
MASTER_LOG,
|
||||
|
|
|
@ -70,6 +70,7 @@ LogManager::LogManager()
|
|||
m_Log[LogTypes::IOS_SSL] = new LogContainer("IOS_SSL", "IOS - SSL");
|
||||
m_Log[LogTypes::IOS_STM] = new LogContainer("IOS_STM", "IOS - State Transition Manager");
|
||||
m_Log[LogTypes::IOS_NET] = new LogContainer("IOS_NET", "IOS - Network");
|
||||
m_Log[LogTypes::IOS_USB] = new LogContainer("IOS_USB", "IOS - USB");
|
||||
m_Log[LogTypes::IOS_WC24] = new LogContainer("IOS_WC24", "IOS - WiiConnect24");
|
||||
m_Log[LogTypes::IOS_WIIMOTE] = new LogContainer("IOS_WIIMOTE", "IOS - Wii Remote");
|
||||
m_Log[LogTypes::MASTER_LOG] = new LogContainer("*", "Master Log");
|
||||
|
|
|
@ -151,6 +151,8 @@ set(SRCS ActionReplay.cpp
|
|||
IOS/Network/SSL.cpp
|
||||
IOS/SDIO/SDIOSlot0.cpp
|
||||
IOS/STM/STM.cpp
|
||||
IOS/USB/Common.cpp
|
||||
IOS/USB/USBV0.cpp
|
||||
IOS/USB/USB_KBD.cpp
|
||||
IOS/USB/USB_VEN.cpp
|
||||
IOS/USB/Bluetooth/BTBase.cpp
|
||||
|
|
|
@ -183,6 +183,8 @@
|
|||
<ClCompile Include="IOS\Network\SSL.cpp" />
|
||||
<ClCompile Include="IOS\SDIO\SDIOSlot0.cpp" />
|
||||
<ClCompile Include="IOS\STM\STM.cpp" />
|
||||
<ClCompile Include="IOS\USB\Common.cpp" />
|
||||
<ClCompile Include="IOS\USB\USBV0.cpp" />
|
||||
<ClCompile Include="IOS\USB\USB_HIDv4.cpp">
|
||||
<!--
|
||||
Disable "nonstandard extension used : zero-sized array in struct/union" warning,
|
||||
|
@ -412,6 +414,8 @@
|
|||
<ClInclude Include="IOS\Network\SSL.h" />
|
||||
<ClInclude Include="IOS\SDIO\SDIOSlot0.h" />
|
||||
<ClInclude Include="IOS\STM\STM.h" />
|
||||
<ClInclude Include="IOS\USB\Common.h" />
|
||||
<ClInclude Include="IOS\USB\USBV0.h" />
|
||||
<ClInclude Include="IOS\USB\USB_HIDv4.h" />
|
||||
<ClInclude Include="IOS\USB\USB_KBD.h" />
|
||||
<ClInclude Include="IOS\USB\USB_VEN.h" />
|
||||
|
|
|
@ -764,6 +764,12 @@
|
|||
<ClCompile Include="IOS\STM\STM.cpp">
|
||||
<Filter>IOS\STM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\USB\Common.cpp">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\USB\USBV0.cpp">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\USB\USB_HIDv4.cpp">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1332,6 +1338,12 @@
|
|||
<ClInclude Include="IOS\STM\STM.h">
|
||||
<Filter>IOS\STM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\USB\Common.h">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\USB\USBV0.h">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\USB\USB_HIDv4.h">
|
||||
<Filter>IOS\USB</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1363,4 +1375,4 @@
|
|||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -53,32 +53,5 @@ void RestoreBTInfoSection(SysConf* sysconf)
|
|||
sysconf->SetArrayData("BT.DINF", section.data(), static_cast<u16>(section.size()));
|
||||
File::Delete(filename);
|
||||
}
|
||||
|
||||
namespace Device
|
||||
{
|
||||
BluetoothBase::CtrlMessage::CtrlMessage(const IOCtlVRequest& ioctlv) : ios_request(ioctlv)
|
||||
{
|
||||
request_type = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||
request = Memory::Read_U8(ioctlv.in_vectors[1].address);
|
||||
value = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[2].address));
|
||||
index = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[3].address));
|
||||
length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address));
|
||||
payload_addr = ioctlv.io_vectors[0].address;
|
||||
}
|
||||
|
||||
BluetoothBase::CtrlBuffer::CtrlBuffer(const IOCtlVRequest& ioctlv) : ios_request(ioctlv)
|
||||
{
|
||||
m_endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||
m_length = Memory::Read_U16(ioctlv.in_vectors[1].address);
|
||||
m_payload_addr = ioctlv.io_vectors[0].address;
|
||||
}
|
||||
|
||||
void BluetoothBase::CtrlBuffer::FillBuffer(const u8* src, const size_t size) const
|
||||
{
|
||||
_assert_msg_(IOS_WIIMOTE, size <= m_length, "FillBuffer: size %li > payload length %i", size,
|
||||
m_length);
|
||||
Memory::CopyToEmu(m_payload_addr, src, size);
|
||||
}
|
||||
} // namespace Device
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
||||
|
|
|
@ -36,13 +36,6 @@ protected:
|
|||
static constexpr int SCO_PKT_SIZE = 64;
|
||||
static constexpr int SCO_PKT_NUM = 0;
|
||||
|
||||
enum USBIOCtl
|
||||
{
|
||||
USBV0_IOCTL_CTRLMSG = 0,
|
||||
USBV0_IOCTL_BLKMSG = 1,
|
||||
USBV0_IOCTL_INTRMSG = 2,
|
||||
};
|
||||
|
||||
enum USBEndpoint
|
||||
{
|
||||
HCI_CTRL = 0x00,
|
||||
|
@ -50,28 +43,6 @@ protected:
|
|||
ACL_DATA_IN = 0x82,
|
||||
ACL_DATA_OUT = 0x02
|
||||
};
|
||||
|
||||
struct CtrlMessage
|
||||
{
|
||||
CtrlMessage(const IOCtlVRequest& ioctlv);
|
||||
IOCtlVRequest ios_request;
|
||||
u8 request_type = 0;
|
||||
u8 request = 0;
|
||||
u16 value = 0;
|
||||
u16 index = 0;
|
||||
u16 length = 0;
|
||||
u32 payload_addr = 0;
|
||||
};
|
||||
|
||||
struct CtrlBuffer
|
||||
{
|
||||
CtrlBuffer(const IOCtlVRequest& ioctlv);
|
||||
IOCtlVRequest ios_request;
|
||||
void FillBuffer(const u8* src, size_t size) const;
|
||||
u8 m_endpoint = 0;
|
||||
u16 m_length = 0;
|
||||
u32 m_payload_addr = 0;
|
||||
};
|
||||
};
|
||||
} // namespace Device
|
||||
} // namespace HLE
|
||||
|
|
|
@ -167,9 +167,9 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request)
|
|||
bool send_reply = true;
|
||||
switch (request.request)
|
||||
{
|
||||
case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack
|
||||
case USB::IOCTLV_USBV0_CTRLMSG: // HCI command is received from the stack
|
||||
{
|
||||
m_CtrlSetup = std::make_unique<CtrlMessage>(request);
|
||||
m_CtrlSetup = std::make_unique<USB::V0CtrlMessage>(request);
|
||||
// Replies are generated inside
|
||||
ExecuteHCICommandMessage(*m_CtrlSetup);
|
||||
m_CtrlSetup.reset();
|
||||
|
@ -177,50 +177,50 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request)
|
|||
break;
|
||||
}
|
||||
|
||||
case USBV0_IOCTL_BLKMSG:
|
||||
case USB::IOCTLV_USBV0_BLKMSG:
|
||||
{
|
||||
const CtrlBuffer ctrl{request};
|
||||
switch (ctrl.m_endpoint)
|
||||
const USB::V0BulkMessage ctrl{request};
|
||||
switch (ctrl.endpoint)
|
||||
{
|
||||
case ACL_DATA_OUT: // ACL data is received from the stack
|
||||
{
|
||||
// This is the ACL datapath from CPU to Wii Remote
|
||||
const auto* acl_header =
|
||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(ctrl.m_payload_addr));
|
||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(ctrl.data_address));
|
||||
|
||||
_dbg_assert_(IOS_WIIMOTE, HCI_BC_FLAG(acl_header->con_handle) == HCI_POINT2POINT);
|
||||
_dbg_assert_(IOS_WIIMOTE, HCI_PB_FLAG(acl_header->con_handle) == HCI_PACKET_START);
|
||||
|
||||
SendToDevice(HCI_CON_HANDLE(acl_header->con_handle),
|
||||
Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)),
|
||||
Memory::GetPointer(ctrl.data_address + sizeof(hci_acldata_hdr_t)),
|
||||
acl_header->length);
|
||||
break;
|
||||
}
|
||||
case ACL_DATA_IN: // We are given an ACL buffer to fill
|
||||
{
|
||||
m_ACLEndpoint = std::make_unique<CtrlBuffer>(request);
|
||||
m_ACLEndpoint = std::make_unique<USB::V0BulkMessage>(request);
|
||||
DEBUG_LOG(IOS_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address);
|
||||
send_reply = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_dbg_assert_msg_(IOS_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint);
|
||||
_dbg_assert_msg_(IOS_WIIMOTE, 0, "Unknown USB::IOCTLV_USBV0_BLKMSG: %x", ctrl.endpoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case USBV0_IOCTL_INTRMSG:
|
||||
case USB::IOCTLV_USBV0_INTRMSG:
|
||||
{
|
||||
const CtrlBuffer ctrl{request};
|
||||
if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
||||
const USB::V0IntrMessage ctrl{request};
|
||||
if (ctrl.endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
||||
{
|
||||
m_HCIEndpoint = std::make_unique<CtrlBuffer>(request);
|
||||
m_HCIEndpoint = std::make_unique<USB::V0IntrMessage>(request);
|
||||
DEBUG_LOG(IOS_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address);
|
||||
send_reply = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbg_assert_msg_(IOS_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint);
|
||||
_dbg_assert_msg_(IOS_WIIMOTE, 0, "Unknown USB::IOCTLV_USBV0_INTRMSG: %x", ctrl.endpoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request)
|
|||
return send_reply ? GetDefaultReply(IPC_SUCCESS) : GetNoReply();
|
||||
}
|
||||
|
||||
// Here we handle the USBV0_IOCTL_BLKMSG Ioctlv
|
||||
// Here we handle the USB::IOCTLV_USBV0_BLKMSG Ioctlv
|
||||
void BluetoothEmu::SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size)
|
||||
{
|
||||
WiimoteDevice* pWiiMote = AccessWiiMote(_ConnectionHandle);
|
||||
|
@ -261,7 +261,7 @@ void BluetoothEmu::SendACLPacket(u16 connection_handle, const u8* data, u32 size
|
|||
m_ACLEndpoint->ios_request.address);
|
||||
|
||||
hci_acldata_hdr_t* header =
|
||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(m_ACLEndpoint->m_payload_addr));
|
||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(m_ACLEndpoint->data_address));
|
||||
header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
||||
header->length = size;
|
||||
|
||||
|
@ -412,7 +412,7 @@ void BluetoothEmu::ACLPool::Store(const u8* data, const u16 size, const u16 conn
|
|||
packet.conn_handle = conn_handle;
|
||||
}
|
||||
|
||||
void BluetoothEmu::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint)
|
||||
void BluetoothEmu::ACLPool::WriteToEndpoint(USB::V0BulkMessage& endpoint)
|
||||
{
|
||||
auto& packet = m_queue.front();
|
||||
|
||||
|
@ -424,7 +424,7 @@ void BluetoothEmu::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint)
|
|||
"queue to %08x",
|
||||
endpoint.ios_request.address);
|
||||
|
||||
hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr);
|
||||
hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.data_address);
|
||||
pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
||||
pHeader->length = size;
|
||||
|
||||
|
@ -964,11 +964,11 @@ bool BluetoothEmu::SendEventConPacketTypeChange(u16 _connectionHandle, u16 _pack
|
|||
}
|
||||
|
||||
// Command dispatcher
|
||||
// This is called from the USBV0_IOCTL_CTRLMSG Ioctlv
|
||||
void BluetoothEmu::ExecuteHCICommandMessage(const CtrlMessage& ctrl_message)
|
||||
// This is called from the USB::IOCTLV_USBV0_CTRLMSG Ioctlv
|
||||
void BluetoothEmu::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_message)
|
||||
{
|
||||
u8* pInput = Memory::GetPointer(ctrl_message.payload_addr + 3);
|
||||
SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.payload_addr);
|
||||
u8* pInput = Memory::GetPointer(ctrl_message.data_address + 3);
|
||||
SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.data_address);
|
||||
|
||||
u16 ocf = HCI_OCF(pMsg->Opcode);
|
||||
u16 ogf = HCI_OGF(pMsg->Opcode);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "Core/IOS/USB/Bluetooth/BTBase.h"
|
||||
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
|
||||
#include "Core/IOS/USB/Bluetooth/hci.h"
|
||||
#include "Core/IOS/USB/USBV0.h"
|
||||
|
||||
class PointerWrap;
|
||||
|
||||
|
@ -70,9 +71,9 @@ private:
|
|||
// this is used to trigger connecting via ACL
|
||||
u8 m_ScanEnable = 0;
|
||||
|
||||
std::unique_ptr<CtrlMessage> m_CtrlSetup;
|
||||
std::unique_ptr<CtrlBuffer> m_HCIEndpoint;
|
||||
std::unique_ptr<CtrlBuffer> m_ACLEndpoint;
|
||||
std::unique_ptr<USB::V0CtrlMessage> m_CtrlSetup;
|
||||
std::unique_ptr<USB::V0IntrMessage> m_HCIEndpoint;
|
||||
std::unique_ptr<USB::V0BulkMessage> m_ACLEndpoint;
|
||||
std::deque<SQueuedEvent> m_EventQueue;
|
||||
|
||||
class ACLPool
|
||||
|
@ -90,7 +91,7 @@ private:
|
|||
ACLPool() : m_queue() {}
|
||||
void Store(const u8* data, const u16 size, const u16 conn_handle);
|
||||
|
||||
void WriteToEndpoint(CtrlBuffer& endpoint);
|
||||
void WriteToEndpoint(USB::V0BulkMessage& endpoint);
|
||||
|
||||
bool IsEmpty() const { return m_queue.empty(); }
|
||||
// For SaveStates
|
||||
|
@ -126,7 +127,7 @@ private:
|
|||
bool SendEventLinkKeyNotification(const u8 num_to_send);
|
||||
|
||||
// Execute HCI Message
|
||||
void ExecuteHCICommandMessage(const CtrlMessage& ctrl_message);
|
||||
void ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_message);
|
||||
|
||||
// OGF 0x01 - Link control commands and return parameters
|
||||
void CommandWriteInquiryMode(const u8* input);
|
||||
|
|
|
@ -178,10 +178,10 @@ IPCCommandResult BluetoothReal::IOCtlV(const IOCtlVRequest& request)
|
|||
switch (request.request)
|
||||
{
|
||||
// HCI commands to the Bluetooth adapter
|
||||
case USBV0_IOCTL_CTRLMSG:
|
||||
case USB::IOCTLV_USBV0_CTRLMSG:
|
||||
{
|
||||
auto cmd = std::make_unique<CtrlMessage>(request);
|
||||
const u16 opcode = Common::swap16(Memory::Read_U16(cmd->payload_addr));
|
||||
auto cmd = std::make_unique<USB::V0CtrlMessage>(request);
|
||||
const u16 opcode = Common::swap16(Memory::Read_U16(cmd->data_address));
|
||||
if (opcode == HCI_CMD_READ_BUFFER_SIZE)
|
||||
{
|
||||
m_fake_read_buffer_size_reply.Set();
|
||||
|
@ -196,68 +196,70 @@ IPCCommandResult BluetoothReal::IOCtlV(const IOCtlVRequest& request)
|
|||
if (opcode == HCI_CMD_DELETE_STORED_LINK_KEY)
|
||||
{
|
||||
// Delete link key(s) from our own link key storage when the game tells the adapter to
|
||||
const auto* delete_cmd =
|
||||
reinterpret_cast<hci_delete_stored_link_key_cp*>(Memory::GetPointer(cmd->payload_addr));
|
||||
if (delete_cmd->delete_all)
|
||||
hci_delete_stored_link_key_cp delete_cmd;
|
||||
Memory::CopyFromEmu(&delete_cmd, cmd->data_address, sizeof(delete_cmd));
|
||||
if (delete_cmd.delete_all)
|
||||
{
|
||||
s_link_keys.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
btaddr_t addr;
|
||||
std::copy(std::begin(delete_cmd->bdaddr.b), std::end(delete_cmd->bdaddr.b), addr.begin());
|
||||
std::copy(std::begin(delete_cmd.bdaddr.b), std::end(delete_cmd.bdaddr.b), addr.begin());
|
||||
s_link_keys.erase(addr);
|
||||
}
|
||||
}
|
||||
auto buffer = std::vector<u8>(cmd->length + LIBUSB_CONTROL_SETUP_SIZE);
|
||||
libusb_fill_control_setup(buffer.data(), cmd->request_type, cmd->request, cmd->value,
|
||||
cmd->index, cmd->length);
|
||||
Memory::CopyFromEmu(buffer.data() + LIBUSB_CONTROL_SETUP_SIZE, cmd->payload_addr, cmd->length);
|
||||
auto buffer = std::make_unique<u8[]>(cmd->length + LIBUSB_CONTROL_SETUP_SIZE);
|
||||
libusb_fill_control_setup(buffer.get(), cmd->request_type, cmd->request, cmd->value, cmd->index,
|
||||
cmd->length);
|
||||
Memory::CopyFromEmu(buffer.get() + LIBUSB_CONTROL_SETUP_SIZE, cmd->data_address, cmd->length);
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
libusb_fill_control_transfer(transfer, m_handle, buffer.data(), CommandCallback, cmd.release(),
|
||||
0);
|
||||
libusb_fill_control_transfer(transfer, m_handle, buffer.release(), CommandCallback,
|
||||
cmd.release(), 0);
|
||||
libusb_submit_transfer(transfer);
|
||||
break;
|
||||
}
|
||||
// ACL data (incoming or outgoing) and incoming HCI events (respectively)
|
||||
case USBV0_IOCTL_BLKMSG:
|
||||
case USBV0_IOCTL_INTRMSG:
|
||||
case USB::IOCTLV_USBV0_BLKMSG:
|
||||
case USB::IOCTLV_USBV0_INTRMSG:
|
||||
{
|
||||
auto buffer = std::make_unique<CtrlBuffer>(request);
|
||||
if (request.request == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear())
|
||||
auto buffer = std::make_unique<USB::V0IntrMessage>(request);
|
||||
if (request.request == USB::IOCTLV_USBV0_INTRMSG)
|
||||
{
|
||||
FakeReadBufferSizeReply(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (request.request == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear())
|
||||
{
|
||||
FakeVendorCommandReply(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::Pressed)
|
||||
{
|
||||
Core::DisplayMessage("Scanning for Wii Remotes", 2000);
|
||||
FakeSyncButtonPressedEvent(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (request.request == USBV0_IOCTL_INTRMSG &&
|
||||
m_sync_button_state == SyncButtonState::LongPressed)
|
||||
{
|
||||
Core::DisplayMessage("Reset saved Wii Remote pairings", 2000);
|
||||
FakeSyncButtonHeldEvent(*buffer);
|
||||
return GetNoReply();
|
||||
if (m_sync_button_state == SyncButtonState::Pressed)
|
||||
{
|
||||
Core::DisplayMessage("Scanning for Wii Remotes", 2000);
|
||||
FakeSyncButtonPressedEvent(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (m_sync_button_state == SyncButtonState::LongPressed)
|
||||
{
|
||||
Core::DisplayMessage("Reset saved Wii Remote pairings", 2000);
|
||||
FakeSyncButtonHeldEvent(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (m_fake_read_buffer_size_reply.TestAndClear())
|
||||
{
|
||||
FakeReadBufferSizeReply(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (m_fake_vendor_command_reply.TestAndClear())
|
||||
{
|
||||
FakeVendorCommandReply(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
}
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
transfer->buffer = Memory::GetPointer(buffer->m_payload_addr);
|
||||
transfer->buffer = Memory::GetPointer(buffer->data_address);
|
||||
transfer->callback = TransferCallback;
|
||||
transfer->dev_handle = m_handle;
|
||||
transfer->endpoint = buffer->m_endpoint;
|
||||
transfer->endpoint = buffer->endpoint;
|
||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
transfer->length = buffer->m_length;
|
||||
transfer->length = buffer->length;
|
||||
transfer->timeout = TIMEOUT;
|
||||
transfer->type = request.request == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK :
|
||||
LIBUSB_TRANSFER_TYPE_INTERRUPT;
|
||||
transfer->type = request.request == USB::IOCTLV_USBV0_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK :
|
||||
LIBUSB_TRANSFER_TYPE_INTERRUPT;
|
||||
transfer->user_data = buffer.release();
|
||||
libusb_submit_transfer(transfer);
|
||||
break;
|
||||
|
@ -390,16 +392,16 @@ bool BluetoothReal::SendHCIStoreLinkKeyCommand()
|
|||
return true;
|
||||
}
|
||||
|
||||
void BluetoothReal::FakeVendorCommandReply(CtrlBuffer& ctrl)
|
||||
void BluetoothReal::FakeVendorCommandReply(USB::V0IntrMessage& ctrl)
|
||||
{
|
||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
||||
hci_event->EventType = HCI_EVENT_COMMAND_COMPL;
|
||||
hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2;
|
||||
hci_event->PacketIndicator = 0x01;
|
||||
hci_event->Opcode = m_fake_vendor_command_reply_opcode;
|
||||
|
||||
EnqueueReply(ctrl.ios_request, static_cast<s32>(sizeof(SHCIEventCommand)));
|
||||
SHCIEventCommand hci_event;
|
||||
Memory::CopyFromEmu(&hci_event, ctrl.data_address, sizeof(hci_event));
|
||||
hci_event.EventType = HCI_EVENT_COMMAND_COMPL;
|
||||
hci_event.PayloadLength = sizeof(SHCIEventCommand) - 2;
|
||||
hci_event.PacketIndicator = 0x01;
|
||||
hci_event.Opcode = m_fake_vendor_command_reply_opcode;
|
||||
Memory::CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
||||
EnqueueReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event)));
|
||||
}
|
||||
|
||||
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
||||
|
@ -407,14 +409,15 @@ void BluetoothReal::FakeVendorCommandReply(CtrlBuffer& ctrl)
|
|||
// - it will cause a u8 underflow and royally screw things up.
|
||||
// Therefore, the reply to this command has to be faked to avoid random, weird issues
|
||||
// (including Wiimote disconnects and "event mismatch" warning messages).
|
||||
void BluetoothReal::FakeReadBufferSizeReply(CtrlBuffer& ctrl)
|
||||
void BluetoothReal::FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl)
|
||||
{
|
||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
||||
hci_event->EventType = HCI_EVENT_COMMAND_COMPL;
|
||||
hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2 + sizeof(hci_read_buffer_size_rp);
|
||||
hci_event->PacketIndicator = 0x01;
|
||||
hci_event->Opcode = HCI_CMD_READ_BUFFER_SIZE;
|
||||
SHCIEventCommand hci_event;
|
||||
Memory::CopyFromEmu(&hci_event, ctrl.data_address, sizeof(hci_event));
|
||||
hci_event.EventType = HCI_EVENT_COMMAND_COMPL;
|
||||
hci_event.PayloadLength = sizeof(SHCIEventCommand) - 2 + sizeof(hci_read_buffer_size_rp);
|
||||
hci_event.PacketIndicator = 0x01;
|
||||
hci_event.Opcode = HCI_CMD_READ_BUFFER_SIZE;
|
||||
Memory::CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
||||
|
||||
hci_read_buffer_size_rp reply;
|
||||
reply.status = 0x00;
|
||||
|
@ -422,27 +425,26 @@ void BluetoothReal::FakeReadBufferSizeReply(CtrlBuffer& ctrl)
|
|||
reply.num_acl_pkts = ACL_PKT_NUM;
|
||||
reply.max_sco_size = SCO_PKT_SIZE;
|
||||
reply.num_sco_pkts = SCO_PKT_NUM;
|
||||
|
||||
memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp));
|
||||
EnqueueReply(ctrl.ios_request,
|
||||
static_cast<s32>(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)));
|
||||
Memory::CopyToEmu(ctrl.data_address + sizeof(hci_event), &reply, sizeof(reply));
|
||||
EnqueueReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event) + sizeof(reply)));
|
||||
}
|
||||
|
||||
void BluetoothReal::FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, const u8 size)
|
||||
void BluetoothReal::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payload, const u8 size)
|
||||
{
|
||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||
auto* hci_event = reinterpret_cast<hci_event_hdr_t*>(packet);
|
||||
hci_event->event = HCI_EVENT_VENDOR;
|
||||
hci_event->length = size;
|
||||
memcpy(packet + sizeof(hci_event_hdr_t), payload, size);
|
||||
EnqueueReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event_hdr_t) + size));
|
||||
hci_event_hdr_t hci_event;
|
||||
Memory::CopyFromEmu(&hci_event, ctrl.data_address, sizeof(hci_event));
|
||||
hci_event.event = HCI_EVENT_VENDOR;
|
||||
hci_event.length = size;
|
||||
Memory::CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
||||
Memory::CopyToEmu(ctrl.data_address + sizeof(hci_event), payload, size);
|
||||
EnqueueReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event) + size));
|
||||
}
|
||||
|
||||
// When the red sync button is pressed, a HCI event is generated:
|
||||
// > HCI Event: Vendor (0xff) plen 1
|
||||
// 08
|
||||
// This causes the emulated software to perform a BT inquiry and connect to found Wiimotes.
|
||||
void BluetoothReal::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl)
|
||||
void BluetoothReal::FakeSyncButtonPressedEvent(USB::V0IntrMessage& ctrl)
|
||||
{
|
||||
NOTICE_LOG(IOS_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet");
|
||||
const u8 payload[1] = {0x08};
|
||||
|
@ -451,7 +453,7 @@ void BluetoothReal::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl)
|
|||
}
|
||||
|
||||
// When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent.
|
||||
void BluetoothReal::FakeSyncButtonHeldEvent(CtrlBuffer& ctrl)
|
||||
void BluetoothReal::FakeSyncButtonHeldEvent(USB::V0IntrMessage& ctrl)
|
||||
{
|
||||
NOTICE_LOG(IOS_WIIMOTE, "Faking 'sync button held' (0x09) event packet");
|
||||
const u8 payload[1] = {0x09};
|
||||
|
@ -565,7 +567,8 @@ void BluetoothReal::TransferThread()
|
|||
// The callbacks are called from libusb code on a separate thread.
|
||||
void BluetoothReal::CommandCallback(libusb_transfer* tr)
|
||||
{
|
||||
const std::unique_ptr<CtrlMessage> cmd(static_cast<CtrlMessage*>(tr->user_data));
|
||||
const std::unique_ptr<USB::CtrlMessage> cmd(static_cast<USB::CtrlMessage*>(tr->user_data));
|
||||
const std::unique_ptr<u8[]> buffer(tr->buffer);
|
||||
if (tr->status != LIBUSB_TRANSFER_COMPLETED && tr->status != LIBUSB_TRANSFER_NO_DEVICE)
|
||||
{
|
||||
ERROR_LOG(IOS_WIIMOTE, "libusb command transfer failed, status: 0x%02x", tr->status);
|
||||
|
@ -580,13 +583,13 @@ void BluetoothReal::CommandCallback(libusb_transfer* tr)
|
|||
{
|
||||
s_showed_failed_transfer.Clear();
|
||||
}
|
||||
|
||||
cmd->FillBuffer(libusb_control_transfer_get_data(tr), tr->actual_length);
|
||||
EnqueueReply(cmd->ios_request, tr->actual_length, 0, CoreTiming::FromThread::NON_CPU);
|
||||
}
|
||||
|
||||
void BluetoothReal::TransferCallback(libusb_transfer* tr)
|
||||
{
|
||||
const std::unique_ptr<CtrlBuffer> ctrl(static_cast<CtrlBuffer*>(tr->user_data));
|
||||
const std::unique_ptr<USB::V0IntrMessage> ctrl(static_cast<USB::V0IntrMessage*>(tr->user_data));
|
||||
if (tr->status != LIBUSB_TRANSFER_COMPLETED && tr->status != LIBUSB_TRANSFER_TIMED_OUT &&
|
||||
tr->status != LIBUSB_TRANSFER_NO_DEVICE)
|
||||
{
|
||||
|
@ -624,7 +627,6 @@ void BluetoothReal::TransferCallback(libusb_transfer* tr)
|
|||
s_need_reset_keys.Set();
|
||||
}
|
||||
}
|
||||
|
||||
EnqueueReply(ctrl->ios_request, tr->actual_length, 0, CoreTiming::FromThread::NON_CPU);
|
||||
}
|
||||
} // namespace Device
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "Common/Timer.h"
|
||||
#include "Core/IOS/IPC.h"
|
||||
#include "Core/IOS/USB/Bluetooth/BTBase.h"
|
||||
#include "Core/IOS/USB/USBV0.h"
|
||||
|
||||
class PointerWrap;
|
||||
struct libusb_context;
|
||||
|
@ -85,11 +86,11 @@ private:
|
|||
void SendHCIResetCommand();
|
||||
void SendHCIDeleteLinkKeyCommand();
|
||||
bool SendHCIStoreLinkKeyCommand();
|
||||
void FakeVendorCommandReply(CtrlBuffer& ctrl);
|
||||
void FakeReadBufferSizeReply(CtrlBuffer& ctrl);
|
||||
void FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, u8 size);
|
||||
void FakeSyncButtonPressedEvent(CtrlBuffer& ctrl);
|
||||
void FakeSyncButtonHeldEvent(CtrlBuffer& ctrl);
|
||||
void FakeVendorCommandReply(USB::V0IntrMessage& ctrl);
|
||||
void FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl);
|
||||
void FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payload, u8 size);
|
||||
void FakeSyncButtonPressedEvent(USB::V0IntrMessage& ctrl);
|
||||
void FakeSyncButtonHeldEvent(USB::V0IntrMessage& ctrl);
|
||||
|
||||
void LoadLinkKeys();
|
||||
void SaveLinkKeys();
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/IOS/USB/Common.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
namespace HLE
|
||||
{
|
||||
namespace USB
|
||||
{
|
||||
std::unique_ptr<u8[]> TransferCommand::MakeBuffer(const size_t size) const
|
||||
{
|
||||
_assert_msg_(IOS_USB, data_address != 0, "Invalid data_address");
|
||||
auto buffer = std::make_unique<u8[]>(size);
|
||||
Memory::CopyFromEmu(buffer.get(), data_address, size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void TransferCommand::FillBuffer(const u8* src, const size_t size) const
|
||||
{
|
||||
_assert_msg_(IOS_USB, size == 0 || data_address != 0, "Invalid data_address");
|
||||
Memory::CopyToEmu(data_address, src, size);
|
||||
}
|
||||
} // namespace USB
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
namespace HLE
|
||||
{
|
||||
namespace USB
|
||||
{
|
||||
struct DeviceDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 bcdUSB;
|
||||
u8 bDeviceClass;
|
||||
u8 bDeviceSubClass;
|
||||
u8 bDeviceProtocol;
|
||||
u8 bMaxPacketSize0;
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
u16 bcdDevice;
|
||||
u8 iManufacturer;
|
||||
u8 iProduct;
|
||||
u8 iSerialNumber;
|
||||
u8 bNumConfigurations;
|
||||
};
|
||||
|
||||
struct ConfigDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
u8 bmAttributes;
|
||||
u8 MaxPower;
|
||||
};
|
||||
|
||||
struct InterfaceDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
u8 bInterfaceClass;
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
u8 iInterface;
|
||||
};
|
||||
|
||||
struct EndpointDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bEndpointAddress;
|
||||
u8 bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
};
|
||||
|
||||
struct TransferCommand
|
||||
{
|
||||
Request ios_request;
|
||||
u32 data_address = 0;
|
||||
|
||||
TransferCommand(const Request& ios_request_, u32 data_address_)
|
||||
: ios_request(ios_request_), data_address(data_address_)
|
||||
{
|
||||
}
|
||||
virtual ~TransferCommand() = default;
|
||||
// Called after a transfer has completed and before replying to the transfer request.
|
||||
virtual void OnTransferComplete() const {}
|
||||
std::unique_ptr<u8[]> MakeBuffer(size_t size) const;
|
||||
void FillBuffer(const u8* src, size_t size) const;
|
||||
};
|
||||
|
||||
struct CtrlMessage : TransferCommand
|
||||
{
|
||||
u8 request_type = 0;
|
||||
u8 request = 0;
|
||||
u16 value = 0;
|
||||
u16 index = 0;
|
||||
u16 length = 0;
|
||||
using TransferCommand::TransferCommand;
|
||||
};
|
||||
|
||||
struct BulkMessage : TransferCommand
|
||||
{
|
||||
u16 length = 0;
|
||||
u8 endpoint = 0;
|
||||
using TransferCommand::TransferCommand;
|
||||
};
|
||||
|
||||
struct IntrMessage : TransferCommand
|
||||
{
|
||||
u16 length = 0;
|
||||
u8 endpoint = 0;
|
||||
using TransferCommand::TransferCommand;
|
||||
};
|
||||
} // namespace USB
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
#include "Core/IOS/USB/USBV0.h"
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
namespace HLE
|
||||
{
|
||||
namespace USB
|
||||
{
|
||||
V0CtrlMessage::V0CtrlMessage(const IOCtlVRequest& ioctlv)
|
||||
: CtrlMessage(ioctlv, ioctlv.io_vectors[0].address)
|
||||
{
|
||||
request_type = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||
request = Memory::Read_U8(ioctlv.in_vectors[1].address);
|
||||
value = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[2].address));
|
||||
index = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[3].address));
|
||||
length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address));
|
||||
}
|
||||
|
||||
V0BulkMessage::V0BulkMessage(const IOCtlVRequest& ioctlv, bool long_length)
|
||||
: BulkMessage(ioctlv, ioctlv.io_vectors[0].address)
|
||||
{
|
||||
endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||
if (long_length)
|
||||
length = Memory::Read_U32(ioctlv.in_vectors[1].address);
|
||||
else
|
||||
length = Memory::Read_U16(ioctlv.in_vectors[1].address);
|
||||
}
|
||||
|
||||
V0IntrMessage::V0IntrMessage(const IOCtlVRequest& ioctlv)
|
||||
: IntrMessage(ioctlv, ioctlv.io_vectors[0].address)
|
||||
{
|
||||
endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||
length = Memory::Read_U16(ioctlv.in_vectors[1].address);
|
||||
}
|
||||
} // namespace USB
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/IOS/USB/Common.h"
|
||||
|
||||
// Used by early USB interfaces, such as /dev/usb/oh0 (except in IOS57, 58, 59) and /dev/usb/oh1.
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
namespace HLE
|
||||
{
|
||||
struct IOCtlVRequest;
|
||||
|
||||
namespace USB
|
||||
{
|
||||
enum V0Requests
|
||||
{
|
||||
IOCTLV_USBV0_CTRLMSG = 0,
|
||||
IOCTLV_USBV0_BLKMSG = 1,
|
||||
IOCTLV_USBV0_INTRMSG = 2,
|
||||
};
|
||||
|
||||
struct V0CtrlMessage final : CtrlMessage
|
||||
{
|
||||
explicit V0CtrlMessage(const IOCtlVRequest& ioctlv);
|
||||
};
|
||||
|
||||
struct V0BulkMessage final : BulkMessage
|
||||
{
|
||||
explicit V0BulkMessage(const IOCtlVRequest& ioctlv, bool long_length = false);
|
||||
};
|
||||
|
||||
struct V0IntrMessage final : IntrMessage
|
||||
{
|
||||
explicit V0IntrMessage(const IOCtlVRequest& ioctlv);
|
||||
};
|
||||
} // namespace USB
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
|
@ -263,8 +263,7 @@ IPCCommandResult USB_HIDv4::IOCtlV(const IOCtlVRequest& request)
|
|||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
void USB_HIDv4::ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest,
|
||||
const struct libusb_device_descriptor* src)
|
||||
void USB_HIDv4::ConvertDeviceToWii(USB::DeviceDescriptor* dest, const libusb_device_descriptor* src)
|
||||
{
|
||||
dest->bLength = src->bLength;
|
||||
dest->bDescriptorType = src->bDescriptorType;
|
||||
|
@ -282,23 +281,22 @@ void USB_HIDv4::ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest,
|
|||
dest->bNumConfigurations = src->bNumConfigurations;
|
||||
}
|
||||
|
||||
void USB_HIDv4::ConvertConfigToWii(WiiHIDConfigDescriptor* dest,
|
||||
const struct libusb_config_descriptor* src)
|
||||
void USB_HIDv4::ConvertConfigToWii(USB::ConfigDescriptor* dest, const libusb_config_descriptor* src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(WiiHIDConfigDescriptor));
|
||||
memcpy(dest, src, sizeof(USB::ConfigDescriptor));
|
||||
dest->wTotalLength = Common::swap16(dest->wTotalLength);
|
||||
}
|
||||
|
||||
void USB_HIDv4::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor* dest,
|
||||
const struct libusb_interface_descriptor* src)
|
||||
void USB_HIDv4::ConvertInterfaceToWii(USB::InterfaceDescriptor* dest,
|
||||
const libusb_interface_descriptor* src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(WiiHIDInterfaceDescriptor));
|
||||
memcpy(dest, src, sizeof(USB::InterfaceDescriptor));
|
||||
}
|
||||
|
||||
void USB_HIDv4::ConvertEndpointToWii(WiiHIDEndpointDescriptor* dest,
|
||||
const struct libusb_endpoint_descriptor* src)
|
||||
void USB_HIDv4::ConvertEndpointToWii(USB::EndpointDescriptor* dest,
|
||||
const libusb_endpoint_descriptor* src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(WiiHIDEndpointDescriptor));
|
||||
memcpy(dest, src, sizeof(USB::EndpointDescriptor));
|
||||
dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize);
|
||||
}
|
||||
|
||||
|
@ -330,7 +328,7 @@ void USB_HIDv4::FillOutDevices(const IOCtlRequest& request)
|
|||
|
||||
OffsetBuffer += 4; // skip devNum for now
|
||||
|
||||
WiiHIDDeviceDescriptor wii_device;
|
||||
USB::DeviceDescriptor wii_device;
|
||||
ConvertDeviceToWii(&wii_device, &desc);
|
||||
Memory::CopyToEmu(OffsetBuffer, &wii_device, wii_device.bLength);
|
||||
OffsetBuffer += Common::AlignUp(wii_device.bLength, 4);
|
||||
|
@ -344,7 +342,7 @@ void USB_HIDv4::FillOutDevices(const IOCtlRequest& request)
|
|||
// do not try to use usb devices with more than one interface, games can crash
|
||||
if (cRet == 0 && config->bNumInterfaces <= MAX_HID_INTERFACES)
|
||||
{
|
||||
WiiHIDConfigDescriptor wii_config;
|
||||
USB::ConfigDescriptor wii_config;
|
||||
ConvertConfigToWii(&wii_config, config);
|
||||
Memory::CopyToEmu(OffsetBuffer, &wii_config, wii_config.bLength);
|
||||
OffsetBuffer += Common::AlignUp(wii_config.bLength, 4);
|
||||
|
@ -361,7 +359,7 @@ void USB_HIDv4::FillOutDevices(const IOCtlRequest& request)
|
|||
if (interface->bInterfaceClass == LIBUSB_CLASS_HID)
|
||||
isHID = true;
|
||||
|
||||
WiiHIDInterfaceDescriptor wii_interface;
|
||||
USB::InterfaceDescriptor wii_interface;
|
||||
ConvertInterfaceToWii(&wii_interface, interface);
|
||||
Memory::CopyToEmu(OffsetBuffer, &wii_interface, wii_interface.bLength);
|
||||
OffsetBuffer += Common::AlignUp(wii_interface.bLength, 4);
|
||||
|
@ -370,7 +368,7 @@ void USB_HIDv4::FillOutDevices(const IOCtlRequest& request)
|
|||
{
|
||||
const struct libusb_endpoint_descriptor* endpoint = &interface->endpoint[e];
|
||||
|
||||
WiiHIDEndpointDescriptor wii_endpoint;
|
||||
USB::EndpointDescriptor wii_endpoint;
|
||||
ConvertEndpointToWii(&wii_endpoint, endpoint);
|
||||
Memory::CopyToEmu(OffsetBuffer, &wii_endpoint, wii_endpoint.bLength);
|
||||
OffsetBuffer += Common::AlignUp(wii_endpoint.bLength, 4);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Common/CommonTypes.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
#include "Core/IOS/IPC.h"
|
||||
#include "Core/IOS/USB/Common.h"
|
||||
|
||||
// Forward declare things which we need from libusb header.
|
||||
// This prevents users of this file from indirectly pulling in libusb.
|
||||
|
@ -61,75 +62,16 @@ private:
|
|||
IOCTL_HID_CANCEL_INTERRUPT = 0x08,
|
||||
};
|
||||
|
||||
struct WiiHIDDeviceDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 bcdUSB;
|
||||
u8 bDeviceClass;
|
||||
u8 bDeviceSubClass;
|
||||
u8 bDeviceProtocol;
|
||||
u8 bMaxPacketSize0;
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
u16 bcdDevice;
|
||||
u8 iManufacturer;
|
||||
u8 iProduct;
|
||||
u8 iSerialNumber;
|
||||
u8 bNumConfigurations;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct WiiHIDConfigDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
u8 bmAttributes;
|
||||
u8 MaxPower;
|
||||
u8 pad[3];
|
||||
};
|
||||
|
||||
struct WiiHIDInterfaceDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
u8 bInterfaceClass;
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
u8 iInterface;
|
||||
u8 pad[3];
|
||||
};
|
||||
|
||||
struct WiiHIDEndpointDescriptor
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bEndpointAddress;
|
||||
u8 bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
u8 bRefresh;
|
||||
u8 bSynchAddress;
|
||||
u8 pad[1];
|
||||
};
|
||||
|
||||
u32 deviceCommandAddress;
|
||||
void FillOutDevices(const IOCtlRequest& request);
|
||||
int GetAvailableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check);
|
||||
bool ClaimDevice(libusb_device_handle* dev);
|
||||
|
||||
void ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest, const libusb_device_descriptor* src);
|
||||
void ConvertConfigToWii(WiiHIDConfigDescriptor* dest, const libusb_config_descriptor* src);
|
||||
void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor* dest,
|
||||
void ConvertDeviceToWii(USB::DeviceDescriptor* dest, const libusb_device_descriptor* src);
|
||||
void ConvertConfigToWii(USB::ConfigDescriptor* dest, const libusb_config_descriptor* src);
|
||||
void ConvertInterfaceToWii(USB::InterfaceDescriptor* dest,
|
||||
const libusb_interface_descriptor* src);
|
||||
void ConvertEndpointToWii(WiiHIDEndpointDescriptor* dest, const libusb_endpoint_descriptor* src);
|
||||
void ConvertEndpointToWii(USB::EndpointDescriptor* dest, const libusb_endpoint_descriptor* src);
|
||||
|
||||
static void checkUsbUpdates(USB_HIDv4* hid);
|
||||
static void LIBUSB_CALL handleUsbUpdates(libusb_transfer* transfer);
|
||||
|
|
Loading…
Reference in New Issue