Diff between 79900d49ac68eb8deeaf6108a97abf26f00daacd and c281bc460884c16ec9314dc4baa858915e412c90

Changed Files

File Additions Deletions Status
plugins/autopair.c +80 -0 modified

Full Patch

diff --git a/plugins/autopair.c b/plugins/autopair.c
index 0b09e89..2274b5e 100644
--- a/plugins/autopair.c
+++ b/plugins/autopair.c
@@ -31,6 +31,80 @@
 #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
  * for keyboard devices.
@@ -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);