IOS: Move out common USB structures
Some structures will be reused and shared between several IOS USB device implementations. This prepares for the upcoming USB PR. I've also removed GetPointer calls in the trivial case (BT passthrough)
This commit is contained in:
parent
25c779943b
commit
954c41d6e9
|
@ -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