From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This moves the pairing handling of wii controllers to autopair plugin. Link: https://github.com/bluez/bluez/issues/911#issuecomment-2571606630 --- plugins/autopair.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/plugins/autopair.c b/plugins/autopair.c index 0b09e893f817..2274b5e2f897 100644 --- a/plugins/autopair.c +++ b/plugins/autopair.c @@ -30,6 +30,80 @@ #include "src/storage.h" #include "src/shared/util.h" +/* + * Nintendo Wii Remote devices require the bdaddr of the host as pin input for + * authentication. This plugin registers a pin-callback and forces this pin + * to be used for authentication. + * + * There are two ways to place the wiimote into discoverable mode. + * - Pressing the red-sync button on the back of the wiimote. This module + * supports pairing via this method. Auto-reconnect should be possible after + * the device was paired once. + * - Pressing the 1+2 buttons on the front of the wiimote. This module does + * not support this method since this method never enables auto-reconnect. + * Hence, pairing is not needed. Use it without pairing if you want. + * After connecting the wiimote you should immediately connect to the input + * service of the wiimote. If you don't, the wiimote will close the connection. + * The wiimote waits about 5 seconds until it turns off again. + * Auto-reconnect is only enabled when pairing with the wiimote via the red + * sync-button and then connecting to the input service. If you do not connect + * to the input service, then auto-reconnect is not enabled. + * If enabled, the wiimote connects to the host automatically when any button + * is pressed. + */ + +static uint16_t wii_ids[][2] = { + { 0x057e, 0x0306 }, /* 1st gen */ + { 0x054c, 0x0306 }, /* LEGO wiimote */ + { 0x057e, 0x0330 }, /* 2nd gen */ +}; + +static const char *wii_names[] = { + "Nintendo RVL-CNT-01", /* 1st gen */ + "Nintendo RVL-CNT-01-TR", /* 2nd gen */ + "Nintendo RVL-CNT-01-UC", /* Wii U Pro Controller */ + "Nintendo RVL-WBC-01", /* Balance Board */ +}; + +static ssize_t wii_pincb(struct btd_adapter *adapter, struct btd_device *device, + char *pinbuf, bool *display, + unsigned int attempt) +{ + uint16_t vendor, product; + char addr[18], name[25]; + unsigned int i; + + /* Only try the pin code once per device. If it's not correct then it's + * an unknown device. + */ + if (attempt > 1) + return 0; + + ba2str(device_get_address(device), addr); + + vendor = btd_device_get_vendor(device); + product = btd_device_get_product(device); + + device_get_name(device, name, sizeof(name)); + + for (i = 0; i < G_N_ELEMENTS(wii_ids); ++i) { + if (vendor == wii_ids[i][0] && product == wii_ids[i][1]) + goto found; + } + + for (i = 0; i < G_N_ELEMENTS(wii_names); ++i) { + if (g_str_equal(name, wii_names[i])) + goto found; + } + + return 0; + +found: + DBG("Forcing fixed pin on detected wiimote %s", addr); + memcpy(pinbuf, btd_adapter_get_address(adapter), 6); + return 6; +} + /* * Plugin to handle automatic pairing of devices with reduced user * interaction, including implementing the recommendation of the HID spec @@ -51,6 +125,12 @@ static ssize_t autopair_pincb(struct btd_adapter *adapter, char name[25]; uint32_t class; uint32_t val; + ssize_t ret; + + /* Try with the wii_pincb first */ + ret = wii_pincb(adapter, device, pinbuf, display, attempt); + if (ret > 0) + return ret; ba2str(device_get_address(device), addr); -- 2.47.1