diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp index 4f6b9d77b0..26a182d8ed 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp @@ -50,24 +50,23 @@ void RestoreBTInfoSection(SysConf* sysconf) File::Delete(filename); } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const SIOCtlVBuffer& cmd_buffer) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - request_type = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - request = Memory::Read_U8(cmd_buffer.InBuffer[1].m_Address); - value = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[2].m_Address)); - index = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[3].m_Address)); - length = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[4].m_Address)); - payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - address = cmd_buffer.m_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)); + payload_addr = ioctlv.io_vectors[0].address; } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, - const u32 command_address) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - m_endpoint = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - m_length = Memory::Read_U16(cmd_buffer.InBuffer[1].m_Address); - m_payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - m_cmd_address = command_address; + 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 CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* src, @@ -77,8 +76,3 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* m_length); Memory::CopyToEmu(m_payload_addr, src, size); } - -void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::SetRetVal(const u32 retval) const -{ - Memory::Write_U32(retval, m_cmd_address + 4); -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h index a880498fa1..d5580299c3 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h @@ -24,11 +24,6 @@ public: : IWII_IPC_HLE_Device(device_id, device_name) { } - virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_base() override = default; - - virtual IPCCommandResult Open(u32 command_address, u32 mode) override = 0; - - virtual void DoState(PointerWrap& p) override = 0; virtual void UpdateSyncButtonState(bool is_held) {} virtual void TriggerSyncButtonPressedEvent() {} @@ -56,31 +51,23 @@ protected: struct CtrlMessage { - CtrlMessage() = default; - CtrlMessage(const SIOCtlVBuffer& cmd_buffer); - + CtrlMessage(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; u8 request_type = 0; u8 request = 0; u16 value = 0; u16 index = 0; u16 length = 0; u32 payload_addr = 0; - u32 address = 0; }; - class CtrlBuffer + struct CtrlBuffer { - public: - CtrlBuffer() = default; - CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, u32 command_address); - + CtrlBuffer(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; void FillBuffer(const u8* src, size_t size) const; - void SetRetVal(const u32 retval) const; - bool IsValid() const { return m_cmd_address != 0; } - void Invalidate() { m_cmd_address = m_payload_addr = 0; } u8 m_endpoint = 0; u16 m_length = 0; u32 m_payload_addr = 0; - u32 m_cmd_address = 0; }; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index 7902659c7c..e22df24c87 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -95,8 +95,6 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu m_ControllerBD.b[4] = 0x00; m_ControllerBD.b[5] = 0xFF; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - Host_SetWiiMoteConnectionState(0); } @@ -106,6 +104,18 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::~CWII_IPC_HLE_Device_usb_oh1_57e_305_em SetUsbPointer(nullptr); } +template +static void DoStateForMessage(PointerWrap& p, std::unique_ptr& message) +{ + u32 request_address = (message != nullptr) ? message->ios_request.address : 0; + p.Do(request_address); + if (request_address != 0) + { + IOSIOCtlVRequest request{request_address}; + message = std::make_unique(request); + } +} + void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) { bool passthrough_bluetooth = false; @@ -119,10 +129,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) p.Do(m_is_active); p.Do(m_ControllerBD); - p.Do(m_CtrlSetup); - p.Do(m_ACLSetup); - p.DoPOD(m_HCIEndpoint); - p.DoPOD(m_ACLEndpoint); + DoStateForMessage(p, m_CtrlSetup); + DoStateForMessage(p, m_HCIEndpoint); + DoStateForMessage(p, m_ACLEndpoint); p.Do(m_last_ticks); p.DoArray(m_PacketCount); p.Do(m_ScanEnable); @@ -138,75 +147,41 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::RemoteDisconnect(u16 _connectionHa return SendEventDisconnect(_connectionHandle, 0x13); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Open(u32 _CommandAddress, u32 _Mode) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close() { + // Clean up state m_ScanEnable = 0; - m_last_ticks = 0; memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; - - m_is_active = true; - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close(u32 _CommandAddress, bool _bForce) -{ - m_ScanEnable = 0; - - m_last_ticks = 0; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; + m_HCIEndpoint.reset(); + m_ACLEndpoint.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(const IOSIOCtlVRequest& request) { - bool _SendReply = false; - - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - switch (CommandBuffer.Parameter) + bool send_reply = true; + switch (request.request) { case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack { - // This is the HCI datapath from CPU to Wii Remote, the USB stuff is little endian.. - m_CtrlSetup.bRequestType = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); - m_CtrlSetup.bRequest = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address); - m_CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address); - m_CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address); - m_CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address); - m_CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address; - m_CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size; - m_CtrlSetup.m_Address = CommandBuffer.m_Address; - - // check termination - _dbg_assert_msg_(WII_IPC_WIIMOTE, - *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0, - "WIIMOTE: Termination != 0"); - + m_CtrlSetup = std::make_unique(request); // Replies are generated inside - ExecuteHCICommandMessage(m_CtrlSetup); + ExecuteHCICommandMessage(*m_CtrlSetup); + m_CtrlSetup.reset(); + send_reply = false; + break; } - break; case USBV0_IOCTL_BLKMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; switch (ctrl.m_endpoint) { case ACL_DATA_OUT: // ACL data is received from the stack { // This is the ACL datapath from CPU to Wii Remote - // Here we only need to record the command address in case we need to delay the reply - m_ACLSetup = CommandBuffer.m_Address; - const auto* acl_header = reinterpret_cast(Memory::GetPointer(ctrl.m_payload_addr)); @@ -216,65 +191,43 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAdd SendToDevice(HCI_CON_HANDLE(acl_header->con_handle), Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)), acl_header->length); - - _SendReply = true; + break; } - break; - case ACL_DATA_IN: // We are given an ACL buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_ACLEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", _CommandAddress); + m_ACLEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address); + send_reply = false; + break; } - break; - default: - { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint); } break; - } } - break; case USBV0_IOCTL_INTRMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_HCIEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", _CommandAddress); + m_HCIEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address); + send_reply = false; } else { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint); } + break; } - break; default: - { - _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown CWII_IPC_HLE_Device_usb_oh1_57e_305: %x", - CommandBuffer.Parameter); - - INFO_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_WIIMOTE); } - // write return value - Memory::Write_U32(0, _CommandAddress + 4); - return _SendReply ? GetDefaultReply() : GetNoReply(); + request.SetReturnValue(IPC_SUCCESS); + return send_reply ? GetDefaultReply() : GetNoReply(); } // Here we handle the USBV0_IOCTL_BLKMSG Ioctlv @@ -302,22 +255,22 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", connection_handle); - if (m_ACLEndpoint.IsValid() && !m_HCIEndpoint.IsValid() && m_EventQueue.empty()) + if (m_ACLEndpoint && !m_HCIEndpoint && m_EventQueue.empty()) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x", - m_ACLEndpoint.m_cmd_address); + m_ACLEndpoint->ios_request.address); hci_acldata_hdr_t* header = - reinterpret_cast(Memory::GetPointer(m_ACLEndpoint.m_payload_addr)); + reinterpret_cast(Memory::GetPointer(m_ACLEndpoint->m_payload_addr)); header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT); header->length = size; // Write the packet to the buffer memcpy(reinterpret_cast(header) + sizeof(hci_acldata_hdr_t), data, header->length); - m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint.m_cmd_address); - m_ACLEndpoint.Invalidate(); + m_ACLEndpoint->ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); + WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request); + m_ACLEndpoint.reset(); } else { @@ -336,17 +289,17 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...", ((hci_event_hdr_t*)_event.m_buffer)->event); - if (m_HCIEndpoint.IsValid()) + if (m_HCIEndpoint) { if (m_EventQueue.empty()) // fast path :) { DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x", - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size); - m_HCIEndpoint.SetRetVal(_event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(_event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); } else // push new one, pop oldest { @@ -357,12 +310,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x " "being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } } @@ -377,24 +330,27 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() { // check HCI queue - if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid()) + if (!m_EventQueue.empty() && m_HCIEndpoint) { // an endpoint has become available, and we have a stored response. const SQueuedEvent& event = m_EventQueue.front(); DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } // check ACL queue - if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty()) - m_acl_pool.WriteToEndpoint(m_ACLEndpoint); + if (!m_acl_pool.IsEmpty() && m_ACLEndpoint && m_EventQueue.empty()) + { + m_acl_pool.WriteToEndpoint(*m_ACLEndpoint); + m_ACLEndpoint.reset(); + } // We wait for ScanEnable to be sent from the Bluetooth stack through HCI_CMD_WRITE_SCAN_ENABLE // before we initiate the connection. @@ -402,7 +358,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() // FiRES: TODO find a better way to do this // Create ACL connection - if (m_HCIEndpoint.IsValid() && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) + if (m_HCIEndpoint && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) { for (auto& wiimote : m_WiiMotes) { @@ -415,7 +371,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() } // Link channels when connected - if (m_ACLEndpoint.IsValid()) + if (m_ACLEndpoint) { for (auto& wiimote : m_WiiMotes) { @@ -469,7 +425,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " "queue to %08x", - endpoint.m_cmd_address); + endpoint.ios_request.address); hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr); pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); @@ -478,12 +434,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe // Write the packet to the buffer std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t)); - endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); + endpoint.ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); m_queue.pop_front(); - WII_IPC_HLE_Interface::EnqueueReply(endpoint.m_cmd_address); - endpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request); } bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete() @@ -1023,10 +978,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventConPacketTypeChange(u16 _ // Command dispatcher // This is called from the USBV0_IOCTL_CTRLMSG Ioctlv void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( - const SHCICommandMessage& _rHCICommandMessage) + const CtrlMessage& ctrl_message) { - u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3); - SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr); + u8* pInput = Memory::GetPointer(ctrl_message.payload_addr + 3); + SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.payload_addr); u16 ocf = HCI_OCF(pMsg->Opcode); u16 ogf = HCI_OGF(pMsg->Opcode); @@ -1110,11 +1065,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( // vendor specific... case 0xFC4C: - CommandVendorSpecific_FC4C(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4C(pInput, ctrl_message.length - 3); break; case 0xFC4F: - CommandVendorSpecific_FC4F(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4F(pInput, ctrl_message.length - 3); break; case HCI_CMD_INQUIRY_CANCEL: @@ -1203,7 +1158,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( } // HCI command is finished, send a reply to command - WII_IPC_HLE_Interface::EnqueueReply(_rHCICommandMessage.m_Address); + WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request); } // diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h index c2986ec676..c3b6ad2cc0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -43,10 +44,8 @@ public: virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_emu(); - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void Update() override; @@ -62,31 +61,16 @@ public: void DoState(PointerWrap& p) override; private: - struct SHCICommandMessage - { - u8 bRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; - - u32 m_PayLoadAddr; - u32 m_PayLoadSize; - u32 m_Address; - }; - bdaddr_t m_ControllerBD; // this is used to trigger connecting via ACL u8 m_ScanEnable = 0; - SHCICommandMessage m_CtrlSetup; - CtrlBuffer m_HCIEndpoint; + std::unique_ptr m_CtrlSetup; + std::unique_ptr m_HCIEndpoint; + std::unique_ptr m_ACLEndpoint; std::deque m_EventQueue; - u32 m_ACLSetup; - CtrlBuffer m_ACLEndpoint; - class ACLPool { struct Packet @@ -109,7 +93,7 @@ private: void DoState(PointerWrap& p) { p.Do(m_queue); } } m_acl_pool; - u32 m_PacketCount[MAX_BBMOTES]; + u32 m_PacketCount[MAX_BBMOTES] = {}; u64 m_last_ticks = 0; // Send ACL data to a device (wiimote) @@ -138,7 +122,7 @@ private: bool SendEventLinkKeyNotification(const u8 num_to_send); // Execute HCI Message - void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage); + void ExecuteHCICommandMessage(const CtrlMessage& ctrl_message); // OGF 0x01 - Link control commands and return parameters void CommandWriteInquiryMode(const u8* input); 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 c3dfb461a7..d4a59d6866 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 @@ -18,6 +18,7 @@ #include "Common/Assert.h" #include "Common/ChunkFile.h" +#include "Common/CommonFuncs.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/Network.h" @@ -89,7 +90,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_real::~CWII_IPC_HLE_Device_usb_oh1_57e_305_r SaveLinkKeys(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(const IOSOpenRequest& request) { libusb_device** list; const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list); @@ -136,18 +137,18 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_addr PanicAlertT("Bluetooth passthrough mode is enabled, " "but no usable Bluetooth USB device was found. Aborting."); Core::QueueHostJob(Core::Stop); - return GetNoReply(); + return IPC_ENOENT; } StartTransferThread(); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close() { - if (!force) + if (m_handle) { libusb_release_interface(m_handle, 0); StopTransferThread(); @@ -156,10 +157,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_add } m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(const IOSIOCtlVRequest& request) { if (!m_is_wii_bt_module && s_need_reset_keys.TestAndClear()) { @@ -170,14 +170,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad WaitForHCICommandComplete(HCI_CMD_WRITE_STORED_LINK_KEY); } - const SIOCtlVBuffer cmd_buffer(command_address); - switch (cmd_buffer.Parameter) + switch (request.request) { // HCI commands to the Bluetooth adapter case USBV0_IOCTL_CTRLMSG: { - auto cmd = std::make_unique(cmd_buffer); - const u16 opcode = *reinterpret_cast(Memory::GetPointer(cmd->payload_addr)); + auto cmd = std::make_unique(request); + const u16 opcode = Common::swap16(Memory::Read_U16(cmd->payload_addr)); if (opcode == HCI_CMD_READ_BUFFER_SIZE) { m_fake_read_buffer_size_reply.Set(); @@ -220,25 +219,24 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad case USBV0_IOCTL_BLKMSG: case USBV0_IOCTL_INTRMSG: { - auto buffer = std::make_unique(cmd_buffer, command_address); - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) + auto buffer = std::make_unique(request); + if (request.request == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) { FakeReadBufferSizeReply(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear()) + if (request.request == 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) + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::Pressed) { Core::DisplayMessage("Scanning for Wii Remotes", 2000); FakeSyncButtonPressedEvent(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::LongPressed) { Core::DisplayMessage("Reset saved Wii Remote pairings", 2000); @@ -253,8 +251,8 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; transfer->length = buffer->m_length; transfer->timeout = TIMEOUT; - transfer->type = cmd_buffer.Parameter == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : - LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->type = request.request == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : + LIBUSB_TRANSFER_TYPE_INTERRUPT; transfer->user_data = buffer.release(); libusb_submit_transfer(transfer); break; @@ -387,7 +385,7 @@ 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) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -395,8 +393,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2; hci_event->PacketIndicator = 0x01; hci_event->Opcode = m_fake_vendor_command_reply_opcode; - ctrl.SetRetVal(sizeof(SHCIEventCommand)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand)); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } // Due to how the widcomm stack which Nintendo uses is coded, we must never @@ -404,7 +402,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const 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 CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -421,11 +419,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const Ctr reply.num_sco_pkts = SCO_PKT_NUM; memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp)); - ctrl.SetRetVal(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuffer& ctrl, +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, const u8 size) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); @@ -433,15 +431,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuf hci_event->event = HCI_EVENT_VENDOR; hci_event->length = size; memcpy(packet + sizeof(hci_event_hdr_t), payload, size); - ctrl.SetRetVal(sizeof(hci_event_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(hci_event_hdr_t) + size); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } // 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 CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet"); const u8 payload[1] = {0x08}; @@ -450,7 +448,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const } // When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent. -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button held' (0x09) event packet"); const u8 payload[1] = {0x09}; @@ -580,7 +578,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer* s_showed_failed_transfer.Clear(); } - WII_IPC_HLE_Interface::EnqueueReply(cmd->address, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, 0, CoreTiming::FromThread::NON_CPU); } void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr) @@ -624,6 +622,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* } } - ctrl->SetRetVal(tr->actual_length); - WII_IPC_HLE_Interface::EnqueueReply(ctrl->m_cmd_address, 0, CoreTiming::FromThread::NON_CPU); + ctrl->ios_request.SetReturnValue(tr->actual_length); + WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, 0, CoreTiming::FromThread::NON_CPU); } 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 1925fca877..6c267264cb 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 @@ -42,9 +42,9 @@ public: CWII_IPC_HLE_Device_usb_oh1_57e_305_real(u32 device_id, const std::string& device_name); ~CWII_IPC_HLE_Device_usb_oh1_57e_305_real() override; - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult Close(u32 command_address, bool force) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void DoState(PointerWrap& p) override; void UpdateSyncButtonState(bool is_held) override; @@ -80,11 +80,11 @@ 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); - void FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl); + 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 LoadLinkKeys(); void SaveLinkKeys(); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp index e4cbd011eb..252cefadf7 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp @@ -12,11 +12,11 @@ namespace Core void DisplayMessage(const std::string& message, int time_in_ms); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(const IOSOpenRequest& request) { PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb." " Passthrough mode cannot be used."); - return GetNoReply(); + return IPC_ENOENT; } void CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::DoState(PointerWrap& p) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h index 074c9cae5c..efb149496e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h @@ -16,11 +16,10 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305_stub final : public CWII_IPC_HLE_Device_usb_oh1_57e_305_base { public: - CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(u32 device_id, const std::string& device_name) + CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(const u32 device_id, const std::string& device_name) : CWII_IPC_HLE_Device_usb_oh1_57e_305_base(device_id, device_name) { } - ~CWII_IPC_HLE_Device_usb_oh1_57e_305_stub() override {} - IPCCommandResult Open(u32 command_address, u32 mode) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; void DoState(PointerWrap& p) override; }; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 6d84534de5..428ccb339e 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 68; // Last changed in PR 4638 +static const u32 STATE_VERSION = 69; // Last changed in PR 4661 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,