LibUSBBluetoothAdapter: Add SendBlockingCommand function.
This commit is contained in:
parent
5336c23329
commit
0e90b85bab
|
@ -14,6 +14,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include <libusb.h>
|
||||
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
@ -62,6 +63,11 @@ bool LibUSBBluetoothAdapter::IsWiiBTModule() const
|
|||
return m_is_wii_bt_module;
|
||||
}
|
||||
|
||||
bool LibUSBBluetoothAdapter::AreCommandsPendingResponse() const
|
||||
{
|
||||
return !m_pending_hci_transfers.empty() || !m_unacknowledged_commands.empty();
|
||||
}
|
||||
|
||||
bool LibUSBBluetoothAdapter::HasConfiguredBluetoothDevice()
|
||||
{
|
||||
const int configured_vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
|
||||
|
@ -159,7 +165,7 @@ LibUSBBluetoothAdapter::~LibUSBBluetoothAdapter()
|
|||
return;
|
||||
|
||||
// Wait for completion (or time out) of all HCI commands.
|
||||
while (!m_pending_hci_transfers.empty() && !m_unacknowledged_commands.empty())
|
||||
while (AreCommandsPendingResponse())
|
||||
{
|
||||
(void)ReceiveHCIEvent();
|
||||
Common::YieldCPU();
|
||||
|
@ -394,6 +400,50 @@ void LibUSBBluetoothAdapter::SendControlTransfer(std::span<const u8> data)
|
|||
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()
|
||||
{
|
||||
constexpr auto callback = LibUSBMemFunCallback<&LibUSBBluetoothAdapter::HandleInputTransfer>();
|
||||
|
|
|
@ -53,6 +53,11 @@ public:
|
|||
// Schedule a transfer to be submitted as soon as possible.
|
||||
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;
|
||||
|
||||
private:
|
||||
|
@ -122,6 +127,7 @@ private:
|
|||
std::deque<OutstandingCommand> m_unacknowledged_commands;
|
||||
|
||||
bool IsControllerReadyForCommand() const;
|
||||
bool AreCommandsPendingResponse() const;
|
||||
|
||||
// Give the transfer to the worker and track the command appropriately.
|
||||
// This should only be used when IsControllerReadyForCommand is true.
|
||||
|
|
Loading…
Reference in New Issue