Blob Blame History Raw
From d3cd88dc5f83e4b23170288eddecd665ad1742eb Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 18:59:06 +0200
Subject: [PATCH 4/9] plugins/sixaxis: Move device discovery to shared header

Move the struct containing the Sixaxis-compatible devices to a
header shared with the input profiles code, so as to reduce device
declaration.

Adding support for new devices should be as easy as adding the device's
declaration in profiles/input/sixaxis.h
---
 plugins/sixaxis.c        | 82 +++++++++++++++++++++-------------------------
 profiles/input/sixaxis.h | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 45 deletions(-)
 create mode 100644 profiles/input/sixaxis.h

diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index c8305d52f..3e8ac06ca 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -48,29 +48,7 @@
 #include "src/plugin.h"
 #include "src/log.h"
 #include "src/shared/util.h"
-
-static const struct {
-	const char *name;
-	uint16_t source;
-	uint16_t vid;
-	uint16_t pid;
-	uint16_t version;
-} devices[] = {
-	{
-		.name = "Sony PLAYSTATION(R)3 Controller",
-		.source = 0x0002,
-		.vid = 0x054c,
-		.pid = 0x0268,
-		.version = 0x0000,
-	},
-	{
-		.name = "Navigation Controller",
-		.source = 0x0002,
-		.vid = 0x054c,
-		.pid = 0x042f,
-		.version = 0x0000,
-	},
-};
+#include "profiles/input/sixaxis.h"
 
 struct authentication_closure {
 	struct btd_adapter *adapter;
@@ -177,7 +155,13 @@ error:
 	g_free(closure);
 }
 
-static bool setup_device(int fd, int index, struct btd_adapter *adapter)
+static bool setup_device(int fd,
+				const char *name,
+				uint16_t source,
+				uint16_t vid,
+				uint16_t pid,
+				uint16_t version,
+				struct btd_adapter *adapter)
 {
 	char device_addr[18];
 	bdaddr_t device_bdaddr;
@@ -207,9 +191,8 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
 
 	info("sixaxis: setting up new device");
 
-	btd_device_device_set_name(device, devices[index].name);
-	btd_device_set_pnpid(device, devices[index].source, devices[index].vid,
-				devices[index].pid, devices[index].version);
+	btd_device_device_set_name(device, name);
+	btd_device_set_pnpid(device, source, vid, pid, version);
 	btd_device_set_temporary(device, true);
 
 	closure = g_try_new0(struct authentication_closure, 1);
@@ -228,12 +211,16 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
 	return true;
 }
 
-static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
+static CablePairingType get_pairing_type_for_device(struct udev_device *udevice,
+								uint16_t  *bus,
+								uint16_t  *vid,
+								uint16_t  *pid,
+								char     **name,
+								uint16_t  *source,
+								uint16_t  *version)
 {
 	struct udev_device *hid_parent;
-	uint16_t vid, pid;
 	const char *hid_id;
-	guint i;
 
 	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
 								"hid", NULL);
@@ -242,45 +229,50 @@ static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
 
 	hid_id = udev_device_get_property_value(hid_parent, "HID_ID");
 
-	if (sscanf(hid_id, "%hx:%hx:%hx", bus, &vid, &pid) != 3)
+	if (sscanf(hid_id, "%hx:%hx:%hx", bus, vid, pid) != 3)
 		return -1;
 
-	for (i = 0; i < G_N_ELEMENTS(devices); i++) {
-		if (devices[i].vid == vid && devices[i].pid == pid)
-			return i;
-	}
-
-	return -1;
+	return get_pairing_type(*vid, *pid, name, source, version);
 }
 
 static void device_added(struct udev_device *udevice)
 {
 	struct btd_adapter *adapter;
-	uint16_t bus;
-	int index;
+	uint16_t bus, vid, pid, source, version;
+	char *name = NULL;
+	CablePairingType type;
 	int fd;
 
 	adapter = btd_adapter_get_default();
 	if (!adapter)
 		return;
 
-	index = get_supported_device(udevice, &bus);
-	if (index < 0)
+	type = get_pairing_type_for_device(udevice,
+						&bus,
+						&vid,
+						&pid,
+						&name,
+						&source,
+						&version);
+	if (type != CABLE_PAIRING_SIXAXIS)
 		return;
 	if (bus != BUS_USB)
 		return;
 
 	info("sixaxis: compatible device connected: %s (%04X:%04X)",
-				devices[index].name, devices[index].vid,
-				devices[index].pid);
+				name, vid, pid);
 
 	fd = open(udev_device_get_devnode(udevice), O_RDWR);
-	if (fd < 0)
+	if (fd < 0) {
+		g_free(name);
 		return;
+	}
 
 	/* Only close the fd if an authentication is not pending */
-	if (!setup_device(fd, index, adapter))
+	if (!setup_device(fd, name, source, vid, pid, version, adapter))
 		close(fd);
+
+	g_free(name);
 }
 
 static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h
new file mode 100644
index 000000000..0b3c4e397
--- /dev/null
+++ b/profiles/input/sixaxis.h
@@ -0,0 +1,85 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2009,2017  Bastien Nocera <hadess@hadess.net>
+ *  Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
+ *  Copyright (C) 2013  Szymon Janc <szymon.janc@gmail.com>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef _SIXAXIS_H_
+#define _SIXAXIS_H_
+
+typedef enum {
+	CABLE_PAIRING_UNSUPPORTED = 0,
+	CABLE_PAIRING_SIXAXIS,
+} CablePairingType;
+
+static inline CablePairingType get_pairing_type(uint16_t   vid,
+						 uint16_t   pid,
+						 char     **name,
+						 uint16_t  *source,
+						 uint16_t  *version)
+{
+	static const struct {
+		const char *name;
+		uint16_t source;
+		uint16_t vid;
+		uint16_t pid;
+		uint16_t version;
+		CablePairingType type;
+	} devices[] = {
+		{
+			.name = "Sony PLAYSTATION(R)3 Controller",
+			.source = 0x0002,
+			.vid = 0x054c,
+			.pid = 0x0268,
+			.version = 0x0000,
+			.type = CABLE_PAIRING_SIXAXIS,
+		},
+		{
+			.name = "Navigation Controller",
+			.source = 0x0002,
+			.vid = 0x054c,
+			.pid = 0x042f,
+			.version = 0x0000,
+			.type = CABLE_PAIRING_SIXAXIS,
+		},
+	};
+	guint i;
+
+	for (i = 0; i < G_N_ELEMENTS(devices); i++) {
+		if (devices[i].vid != vid)
+			continue;
+		if (devices[i].pid != pid)
+			continue;
+
+		if (name)
+			*name = g_strdup(devices[i].name);
+		if (source)
+			*source = devices[i].source;
+		if (version)
+			*version = devices[i].version;
+		return devices[i].type;
+	}
+
+	return CABLE_PAIRING_UNSUPPORTED;
+}
+
+#endif /* _SIXAXIS_H_ */
-- 
2.14.1