feat(linux): allow configuring real wiimotes with known bluetooth addresses

This adds the option to configure real Wiimotes by specifying their Bluetooth addresses in
the configuration file.  This allows off-brand Wiimotes to work without using the
Bluetooth Passthrough option, if you know their Bluetooth addresses beforehand.

Despite correctly setting the LAP to `0x9e8b00` in `WiimoteScannerLinux::FindWiimotes`
while scanning, which is indeed enough to make off-brand / knock-off Wiimotes respond to a
Bluetooth Inquiry, some (several? all?) bluetooth adapters seem to override and ignore
this given LAP value when performing the Inquiry, and actually use the `0x9e8b33` value as
if a null pointer have been given to `hci_inquiry`, as inspection of USB/Bluetooth packets
by Wireshark indicate.  Off-brand Wiimotes don't respond to inquiries with this LAP.

If one happens to know the Bluetooth address of their Wiimote (for example, by checking
`BluetoothPassthrough.LinkKeys` after using Bluetooth Passthrough, or other means such as
directly using `libusb` to force the adapter to use the correct LAP in the Inquiry), then
it's enough to add those addresses to the vector of found Wiimotes.

Since this a niche use case and I only happen to know and have tested in Linux, this
change only affects the `WiimoteScannerLinux` backend.  It's likely that it could be added
to other backends, but I'm unfamiliar with these.

If no addresses are given or this config section does not exist, behavior is completely
unchanged.
This commit is contained in:
Thales MG 2024-12-25 14:09:00 -03:00
parent 57b1234feb
commit 4c50f5b55e
4 changed files with 35 additions and 0 deletions

View File

@ -523,6 +523,11 @@ const Info<int> MAIN_BLUETOOTH_PASSTHROUGH_PID{{System::Main, "BluetoothPassthro
const Info<std::string> MAIN_BLUETOOTH_PASSTHROUGH_LINK_KEYS{
{System::Main, "BluetoothPassthrough", "LinkKeys"}, ""};
// Main.RealWiimote
const Info<std::string> MAIN_REAL_WIIMOTE_KNOWN_ADDRESSES{
{System::Main, "RealWiimote", "KnownAddresses"}, ""};
// Main.USBPassthrough
const Info<std::string> MAIN_USB_PASSTHROUGH_DEVICES{{System::Main, "USBPassthrough", "Devices"},

View File

@ -345,6 +345,10 @@ extern const Info<int> MAIN_BLUETOOTH_PASSTHROUGH_VID;
extern const Info<int> MAIN_BLUETOOTH_PASSTHROUGH_PID;
extern const Info<std::string> MAIN_BLUETOOTH_PASSTHROUGH_LINK_KEYS;
// Main.RealWiimote
extern const Info<std::string> MAIN_REAL_WIIMOTE_KNOWN_ADDRESSES;
// Main.USBPassthrough
extern const Info<std::string> MAIN_USB_PASSTHROUGH_DEVICES;

View File

@ -12,6 +12,7 @@
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Core/Config/MainSettings.h"
namespace WiimoteReal
{
@ -50,6 +51,8 @@ bool WiimoteScannerLinux::IsReady() const
void WiimoteScannerLinux::FindWiimotes(std::vector<Wiimote*>& found_wiimotes, Wiimote*& found_board)
{
WiimoteScannerLinux::AddKnownAddresses(found_wiimotes);
// supposedly 1.28 seconds
int const wait_len = 1;
@ -110,6 +113,27 @@ void WiimoteScannerLinux::FindWiimotes(std::vector<Wiimote*>& found_wiimotes, Wi
}
}
void WiimoteScannerLinux::AddKnownAddresses(std::vector<Wiimote*>& found_wiimotes)
{
std::string entries = Config::Get(Config::MAIN_REAL_WIIMOTE_KNOWN_ADDRESSES);
if (entries.empty())
return;
for (const auto& bt_address_str : SplitString(entries, ','))
{
bdaddr_t bt_addr;
if (str2ba(bt_address_str.c_str(), &bt_addr) < 0)
{
WARN_LOG_FMT(WIIMOTE, "Bad Known Bluetooth Address: {}", bt_address_str);
continue;
}
if (!IsNewWiimote(bt_address_str))
continue;
Wiimote* wm = new WiimoteLinux(bt_addr);
found_wiimotes.push_back(wm);
NOTICE_LOG_FMT(WIIMOTE, "Added Wiimote with fixed address ({}).", bt_address_str);
}
}
WiimoteLinux::WiimoteLinux(bdaddr_t bdaddr) : m_bdaddr(bdaddr)
{
m_really_disconnect = true;

View File

@ -50,6 +50,8 @@ public:
private:
int m_device_id;
int m_device_sock;
void AddKnownAddresses(std::vector<Wiimote*>&);
};
} // namespace WiimoteReal