summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLéo Lam <leo@innovatetechnologi.es>2016-09-27 21:33:45 +0200
committerLéo Lam <leo@innovatetechnologi.es>2016-10-03 23:13:09 +0200
commitb91095a9fc2a92e425eb4920206785e12dc251cd (patch)
tree3e5b352ad1c2f96e577552549d3189cd8b516636 /Source/Core
parent5b50b1e1aa3923fa46c3407885d44a7cbc570d4d (diff)
IPC_HLE/57e_305: Fake vendor-specific command replies
Homebrew programs seem to rely on getting a reply to the vendor specific commands, without which Bluetooth initialisation will never complete. This vendor-specific command is typically used to patch the Wii's Bluetooth module, so the replies are only faked when the passed through adapter is not a Wii Bluetooth module.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp23
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h5
2 files changed, 27 insertions, 1 deletions
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp
index b6a5b5b8db..27bddc8361 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp
@@ -171,6 +171,12 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
m_fake_read_buffer_size_reply.Set();
return GetNoReply();
}
+ if (!m_is_wii_bt_module && (opcode == 0xFC4C || opcode == 0xFC4F))
+ {
+ m_fake_vendor_command_reply.Set();
+ m_fake_vendor_command_reply_opcode = opcode;
+ return GetNoReply();
+ }
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
@@ -208,6 +214,11 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
FakeReadBufferSizeReply(*buffer);
return GetNoReply();
}
+ if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear())
+ {
+ FakeVendorCommandReply(*buffer);
+ return GetNoReply();
+ }
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG &&
m_sync_button_state == SyncButtonState::Pressed)
{
@@ -364,6 +375,18 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_real::SendHCIStoreLinkKeyCommand()
return true;
}
+void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const CtrlBuffer& 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;
+ ctrl.SetRetVal(sizeof(SHCIEventCommand));
+ EnqueueReply(ctrl.m_cmd_address);
+}
+
// Due to how the widcomm stack which Nintendo uses is coded, we must never
// let the stack think the controller is buffering more than 10 data packets
// - it will cause a u8 underflow and royally screw things up.
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h
index b55e23ebc8..3bab9db86b 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h
@@ -68,8 +68,10 @@ private:
Common::Flag m_thread_running;
std::thread m_thread;
- // Set when we received a command to read the buffer size, and we need to fake a reply
+ // Set when we received a command to which we need to fake a reply
Common::Flag m_fake_read_buffer_size_reply;
+ Common::Flag m_fake_vendor_command_reply;
+ u16 m_fake_vendor_command_reply_opcode;
bool m_is_wii_bt_module = false;
@@ -77,6 +79,7 @@ private:
void SendHCIResetCommand();
void SendHCIDeleteLinkKeyCommand();
bool SendHCIStoreLinkKeyCommand();
+ void FakeVendorCommandReply(const CtrlBuffer& ctrl);
void FakeReadBufferSizeReply(const CtrlBuffer& ctrl);
void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size);
void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl);