mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-22 02:09:06 +00:00
LibUSBBluetoothAdapter: Add SendBlockingCommand function.
This commit is contained in:
parent
5336c23329
commit
0e90b85bab
2 changed files with 57 additions and 1 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
|
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
@ -62,6 +63,11 @@ bool LibUSBBluetoothAdapter::IsWiiBTModule() const
|
||||||
return m_is_wii_bt_module;
|
return m_is_wii_bt_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LibUSBBluetoothAdapter::AreCommandsPendingResponse() const
|
||||||
|
{
|
||||||
|
return !m_pending_hci_transfers.empty() || !m_unacknowledged_commands.empty();
|
||||||
|
}
|
||||||
|
|
||||||
bool LibUSBBluetoothAdapter::HasConfiguredBluetoothDevice()
|
bool LibUSBBluetoothAdapter::HasConfiguredBluetoothDevice()
|
||||||
{
|
{
|
||||||
const int configured_vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
|
const int configured_vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
|
||||||
|
@ -159,7 +165,7 @@ LibUSBBluetoothAdapter::~LibUSBBluetoothAdapter()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Wait for completion (or time out) of all HCI commands.
|
// Wait for completion (or time out) of all HCI commands.
|
||||||
while (!m_pending_hci_transfers.empty() && !m_unacknowledged_commands.empty())
|
while (AreCommandsPendingResponse())
|
||||||
{
|
{
|
||||||
(void)ReceiveHCIEvent();
|
(void)ReceiveHCIEvent();
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
|
@ -394,6 +400,50 @@ void LibUSBBluetoothAdapter::SendControlTransfer(std::span<const u8> data)
|
||||||
ScheduleControlTransfer(REQUEST_TYPE, 0, 0, 0, data, Clock::now());
|
ScheduleControlTransfer(REQUEST_TYPE, 0, 0, 0, data, Clock::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LibUSBBluetoothAdapter::SendBlockingCommand(std::span<const u8> data, std::span<u8> response)
|
||||||
|
{
|
||||||
|
SendControlTransfer(data);
|
||||||
|
|
||||||
|
const hci_cmd_hdr_t cmd = Common::BitCastPtr<hci_cmd_hdr_t>(data.data());
|
||||||
|
|
||||||
|
while (AreCommandsPendingResponse())
|
||||||
|
{
|
||||||
|
const auto event = ReceiveHCIEvent();
|
||||||
|
|
||||||
|
if (event.empty())
|
||||||
|
{
|
||||||
|
Common::YieldCPU();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event[0] != HCI_EVENT_COMMAND_COMPL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (event.size() < sizeof(hci_event_hdr_t) + sizeof(hci_command_compl_ep))
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WIIMOTE, "Undersized hci_command_compl_ep");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hci_command_compl_ep compl_event =
|
||||||
|
Common::BitCastPtr<hci_command_compl_ep>(event.data() + sizeof(hci_event_hdr_t));
|
||||||
|
if (compl_event.opcode != cmd.opcode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (event.size() < sizeof(hci_event_hdr_t) + sizeof(hci_command_compl_ep) + response.size())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WIIMOTE, "Undersized command result");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy_n(event.data() + sizeof(hci_event_hdr_t) + sizeof(hci_command_compl_ep),
|
||||||
|
response.size(), response.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LibUSBBluetoothAdapter::StartInputTransfers()
|
void LibUSBBluetoothAdapter::StartInputTransfers()
|
||||||
{
|
{
|
||||||
constexpr auto callback = LibUSBMemFunCallback<&LibUSBBluetoothAdapter::HandleInputTransfer>();
|
constexpr auto callback = LibUSBMemFunCallback<&LibUSBBluetoothAdapter::HandleInputTransfer>();
|
||||||
|
|
|
@ -53,6 +53,11 @@ public:
|
||||||
// Schedule a transfer to be submitted as soon as possible.
|
// Schedule a transfer to be submitted as soon as possible.
|
||||||
void SendControlTransfer(std::span<const u8> data);
|
void SendControlTransfer(std::span<const u8> data);
|
||||||
|
|
||||||
|
// Blocks and eats events until a command complete event of the correct opcode is received.
|
||||||
|
// Returns true on success or false on error or timeout.
|
||||||
|
// The written response does not include the event header or command complete data.
|
||||||
|
bool SendBlockingCommand(std::span<const u8> data, std::span<u8> response);
|
||||||
|
|
||||||
bool IsWiiBTModule() const;
|
bool IsWiiBTModule() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -122,6 +127,7 @@ private:
|
||||||
std::deque<OutstandingCommand> m_unacknowledged_commands;
|
std::deque<OutstandingCommand> m_unacknowledged_commands;
|
||||||
|
|
||||||
bool IsControllerReadyForCommand() const;
|
bool IsControllerReadyForCommand() const;
|
||||||
|
bool AreCommandsPendingResponse() const;
|
||||||
|
|
||||||
// Give the transfer to the worker and track the command appropriately.
|
// Give the transfer to the worker and track the command appropriately.
|
||||||
// This should only be used when IsControllerReadyForCommand is true.
|
// This should only be used when IsControllerReadyForCommand is true.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue