PairingDialog: Implement 'pairing' for bluez, reformat file

This commit is contained in:
capitalistspz 2024-09-26 02:50:02 +01:00
parent 0d4176aab0
commit 00ff45d66b
3 changed files with 214 additions and 168 deletions

View file

@ -4,6 +4,12 @@
#if BOOST_OS_WINDOWS
#include <bluetoothapis.h>
#endif
#if BOOST_OS_LINUX
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <input/api/Wiimote/l2cap/L2CapWiimote.h>
#endif
wxDECLARE_EVENT(wxEVT_PROGRESS_PAIR, wxCommandEvent);
wxDEFINE_EVENT(wxEVT_PROGRESS_PAIR, wxCommandEvent);
@ -91,9 +97,9 @@ void PairingDialog::OnGaugeUpdate(wxCommandEvent& event)
break;
}
case PairingState::BluetoothFailed:
case PairingState::SearchFailed:
{
m_text->SetLabel(_("Failed to search for controllers."));
m_text->SetLabel(_("Failed to find controllers."));
m_gauge->SetValue(0);
m_cancelButton->SetLabel(_("Close"));
break;
@ -115,7 +121,6 @@ void PairingDialog::OnGaugeUpdate(wxCommandEvent& event)
break;
}
default:
{
break;
@ -123,18 +128,17 @@ void PairingDialog::OnGaugeUpdate(wxCommandEvent& event)
}
}
#if BOOST_OS_WINDOWS
void PairingDialog::WorkerThread()
{
const std::wstring wiimoteName = L"Nintendo RVL-CNT-01";
const std::wstring wiiUProControllerName = L"Nintendo RVL-CNT-01-UC";
#if BOOST_OS_WINDOWS
const GUID bthHidGuid = {0x00001124,0x0000,0x1000,{0x80,0x00,0x00,0x80,0x5F,0x9B,0x34,0xFB}};
const GUID bthHidGuid = {0x00001124, 0x0000, 0x1000, {0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}};
const BLUETOOTH_FIND_RADIO_PARAMS radioFindParams =
{
.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS)
};
.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS)};
HANDLE radio = INVALID_HANDLE_VALUE;
HBLUETOOTH_RADIO_FIND radioFind = BluetoothFindFirstRadio(&radioFindParams, &radio);
@ -148,8 +152,7 @@ void PairingDialog::WorkerThread()
BLUETOOTH_RADIO_INFO radioInfo =
{
.dwSize = sizeof(BLUETOOTH_RADIO_INFO)
};
.dwSize = sizeof(BLUETOOTH_RADIO_INFO)};
DWORD result = BluetoothGetRadioInfo(radio, &radioInfo);
if (result != ERROR_SUCCESS)
@ -170,13 +173,11 @@ void PairingDialog::WorkerThread()
.fIssueInquiry = TRUE,
.cTimeoutMultiplier = 5,
.hRadio = radio
};
.hRadio = radio};
BLUETOOTH_DEVICE_INFO info =
{
.dwSize = sizeof(BLUETOOTH_DEVICE_INFO)
};
.dwSize = sizeof(BLUETOOTH_DEVICE_INFO)};
while (!m_threadShouldQuit)
{
@ -195,7 +196,7 @@ void PairingDialog::WorkerThread()
UpdateCallback(PairingState::Pairing);
wchar_t passwd[6] = { radioInfo.address.rgBytes[0], radioInfo.address.rgBytes[1], radioInfo.address.rgBytes[2], radioInfo.address.rgBytes[3], radioInfo.address.rgBytes[4], radioInfo.address.rgBytes[5] };
wchar_t passwd[6] = {radioInfo.address.rgBytes[0], radioInfo.address.rgBytes[1], radioInfo.address.rgBytes[2], radioInfo.address.rgBytes[3], radioInfo.address.rgBytes[4], radioInfo.address.rgBytes[5]};
DWORD bthResult = BluetoothAuthenticateDevice(nullptr, radio, &info, passwd, 6);
if (bthResult != ERROR_SUCCESS)
{
@ -223,11 +224,56 @@ void PairingDialog::WorkerThread()
BluetoothFindDeviceClose(deviceFind);
}
#else
UpdateCallback(PairingState::BluetoothUnusable);
#endif
}
#elif BOOST_OS_LINUX
void PairingDialog::WorkerThread()
{
constexpr static uint8_t liacLap[] = {0x00, 0x8b, 0x9e};
constexpr static auto isWiimoteName = [](std::string_view name) {
return name == "Nintendo RVL-CNT-01" || name == "Nintendo RVL-CNT-01-TR";
};
// Get default BT device
const auto hostId = hci_get_route(nullptr);
if (hostId < 0)
{
UpdateCallback(PairingState::NoBluetoothAvailable);
return;
}
// Search for device
inquiry_info* info = nullptr;
const auto respCount = hci_inquiry(hostId, 5, 1, liacLap, &info, IREQ_CACHE_FLUSH);
if (respCount <= 0)
{
UpdateCallback(PairingState::SearchFailed);
return;
}
//! Open dev to read name
const auto hostDesc = hci_open_dev(hostId);
char nameBuffer[HCI_MAX_NAME_LENGTH] = {};
// Get device name and compare. Would use product and vendor id from SDP, but many third-party Wiimotes don't store them
auto& addr = info->bdaddr;
if (hci_read_remote_name(hostDesc, &addr, HCI_MAX_NAME_LENGTH, nameBuffer,
2000) != 0 || !isWiimoteName(nameBuffer))
{
UpdateCallback(PairingState::SearchFailed);
return;
}
cemuLog_log(LogType::Force, "Pairing Dialog: Found '{}' with address {:02x}", nameBuffer, fmt::join(addr.b, ":"));
UpdateCallback(PairingState::Finished);
L2CapWiimote::AddCandidateAddress(addr);
}
#else
void PairingDialog::WorkerThread()
{
UpdateCallback(PairingState::BluetoothUnusable);
}
#endif
void PairingDialog::UpdateCallback(PairingState state)
{
auto* event = new wxCommandEvent(wxEVT_PROGRESS_PAIR);

View file

@ -17,7 +17,7 @@ private:
Pairing,
Finished,
NoBluetoothAvailable,
BluetoothFailed,
SearchFailed,
PairingFailed,
BluetoothUnusable
};

View file

@ -1,5 +1,5 @@
#pragma once
#include <api/Wiimote/WiimoteDevice.h>
#include <input/api/Wiimote/WiimoteDevice.h>
#include <bluetooth/bluetooth.h>
class L2CapWiimote : public WiimoteDevice
@ -12,7 +12,7 @@ class L2CapWiimote : public WiimoteDevice
std::optional<std::vector<uint8>> read_data() override;
bool operator==(WiimoteDevice& o) const override;
static void AddCandidateAddresses(const std::vector<bdaddr_t>& addrs);
static void AddCandidateAddress(bdaddr_t addr);
static std::vector<WiimoteDevicePtr> get_devices();
private:
int m_recvFd;