diff mbox

[0/4,incremental,1/2] Generalize controller handling to support different devices

Message ID 1313677340-4441-1-git-send-email-ospite@studenti.unina.it
State New, archived
Headers show

Commit Message

Antonio Ospite Aug. 18, 2011, 2:22 p.m. UTC
Remove hardcoded #defines and put the values in a struct so we can handle

Comments

Alan Ott Aug. 18, 2011, 3:26 p.m. UTC | #1
On 08/18/2011 10:22 AM, Antonio Ospite wrote:
> Remove hardcoded #defines and put the values in a struct so we can handle 
> different device types.
>
> From the USB dumps I've seen[1], different devices have just different ways to 
> get and set the bdaddrs, the pairing algorithm is the same.
>
> [1] http://ps3.jim.sh/sixaxis/dumps/ 
>
> ---
>  plugins/sixaxis.c |   80 ++++++++++++++++++++++++++++++++++------------------
>  1 files changed, 52 insertions(+), 28 deletions(-)
>
> diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
> index e08222c..608474f 100644
> --- a/plugins/sixaxis.c
> +++ b/plugins/sixaxis.c
> @@ -70,12 +70,38 @@
>  
>  #define BDADDR_STR_SIZE 18 /* strlen("00:00:00:00:00:00") + 1 */
>  
> -/* Vendor and product ID for the Sixaxis PS3 controller */
> -#define VENDOR 0x054c
> -#define PRODUCT 0x0268
> -#define SIXAXIS_NAME "PLAYSTATION(R)3 Controller"
> -#define SIXAXIS_PNP_RECORD "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800"
> -#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
> +struct sony_controller {
> +	uint16_t vendor_id;
> +	uint16_t product_id;
> +	char *name;
> +	char *pnp_record;
> +	char *hid_uuid;
> +
> +	/* device specific callbacks to get master/device bdaddr and set
> +	 * master bdaddr
> +	 */
> +	char * (*get_device_bdaddr)(int);
> +	char * (*get_master_bdaddr)(int);
> +	int (*set_master_bdaddr) (int, char *);
> +};
> +
> +static char *sixaxis_get_device_bdaddr(int fd);
> +static char *sixaxis_get_master_bdaddr(int fd);
> +static int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr);
> +
> +static struct sony_controller controllers[] = {
> +	{
> +		.vendor_id = 0x054c,
> +		.product_id = 0x0268,
> +		.name = "PLAYSTATION(R)3 Controller",
> +		.pnp_record = "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800",
> +		.hid_uuid = "00001124-0000-1000-8000-00805f9b34fb",

Where do the pnp_record and hid_uuid come from? It seems a bit odd to
have a giant hard-coded identifier string (pnp), but I'm not an expert
on this stuff, and I'm mostly just curious about it.

> +		.get_device_bdaddr = sixaxis_get_device_bdaddr,
> +		.get_master_bdaddr = sixaxis_get_master_bdaddr,
> +		.set_master_bdaddr = sixaxis_set_master_bdaddr,
> +	},
> +};
> +
>  
>  #define LED_1 (0x01 << 1)
>  #define LED_2 (0x01 << 2)
> @@ -90,12 +116,9 @@ static struct udev_monitor *monitor;
>  static guint watch_id;
>  
>  
> -static int create_sixaxis_association(struct btd_adapter *adapter,
> -					const char *name,
> +static int create_controller_association(struct btd_adapter *adapter,
>  					const char *address,
> -					guint32 vendor_id,
> -					guint32 product_id,
> -					const char *pnp_record)
> +					struct sony_controller *controller)
>  {
>  	DBusConnection *conn;
>  	sdp_record_t *rec;
> @@ -108,15 +131,16 @@ static int create_sixaxis_association(struct btd_adapter *adapter,
>  	adapter_get_address(adapter, &src);
>  	ba2str(&src, srcaddr);
>  
> -	write_device_name(&dst, &src, (char *) name);
> +	write_device_name(&dst, &src, controller->name);
>  
>  	/* Store the device's SDP record */
> -	rec = record_from_string(pnp_record);
> +	rec = record_from_string(controller->pnp_record);
>  	store_record(srcaddr, address, rec);
>  	sdp_record_free(rec);
>  
>  	/* Set the device id */
> -	store_device_id(srcaddr, address, 0xffff, vendor_id, product_id, 0);
> +	store_device_id(srcaddr, address, 0xffff, controller->vendor_id,
> +			controller->product_id, 0);
>  	/* Don't write a profile here,
>  	 * it will be updated when the device connects */
>  
> @@ -137,8 +161,8 @@ static int create_sixaxis_association(struct btd_adapter *adapter,
>  	}
>  
>  	device_set_temporary(device, FALSE);
> -	device_set_name(device, name);
> -	btd_device_add_uuid(device, HID_UUID);
> +	device_set_name(device, controller->name);
> +	btd_device_add_uuid(device, controller->hid_uuid);
>  
>  fail_device:
>  	dbus_connection_unref(conn);
> @@ -184,7 +208,7 @@ static int set_feature_report(int fd, uint8_t *report, int len)
>  	return ret;
>  }
>  
> -static char *get_device_bdaddr(int fd)
> +static char *sixaxis_get_device_bdaddr(int fd)
>  {
>  	unsigned char *buf;
>  	char *address;
> @@ -210,7 +234,7 @@ static char *get_device_bdaddr(int fd)
>  	return address;
>  }
>  
> -static char *get_master_bdaddr(int fd)
> +static char *sixaxis_get_master_bdaddr(int fd)
>  {
>  	unsigned char *buf;
>  	char *address;
> @@ -236,7 +260,7 @@ static char *get_master_bdaddr(int fd)
>  	return address;
>  }
>  
> -static int set_master_bdaddr(int fd, char *adapter_bdaddr)
> +static int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr)
>  {
>  	uint8_t *report;
>  	uint8_t addr[6];
> @@ -282,7 +306,7 @@ out:
>  	return ret;
>  }
>  
> -static int sixpair(int fd, struct btd_adapter *adapter)
> +static int controller_pair(int fd, struct btd_adapter *adapter, struct sony_controller *controller)
>  {
>  	char *device_bdaddr;
>  	char *master_bdaddr;
> @@ -294,7 +318,7 @@ static int sixpair(int fd, struct btd_adapter *adapter)
>  	ba2str(&dst, adapter_bdaddr);
>  	DBG("Adapter bdaddr %s", adapter_bdaddr);
>  
> -	master_bdaddr = get_master_bdaddr(fd);
> +	master_bdaddr = controller->get_master_bdaddr(fd);
>  	if (master_bdaddr == NULL) {
>  		DBG("Failed to get the Old master Bluetooth address from the device");
>  		return -EPERM;
> @@ -305,7 +329,7 @@ static int sixpair(int fd, struct btd_adapter *adapter)
>  	 */
>  	if (g_strcmp0(master_bdaddr, adapter_bdaddr) != 0) {
>  		DBG("Old master Bluetooth address was: %s", master_bdaddr);
> -		ret = set_master_bdaddr(fd, adapter_bdaddr);
> +		ret = controller->set_master_bdaddr(fd, adapter_bdaddr);
>  		if (ret < 0) {
>  			DBG("Failed to set the master Bluetooth address");
>  			free(master_bdaddr);
> @@ -313,7 +337,7 @@ static int sixpair(int fd, struct btd_adapter *adapter)
>  		}
>  	}
>  
> -	device_bdaddr = get_device_bdaddr(fd);
> +	device_bdaddr = controller->get_device_bdaddr(fd);
>  	if (device_bdaddr == NULL) {
>  		DBG("Failed to get the Bluetooth address from the device");
>  		free(master_bdaddr);
> @@ -322,10 +346,7 @@ static int sixpair(int fd, struct btd_adapter *adapter)
>  
>  	DBG("Device bdaddr %s", device_bdaddr);
>  
> -	ret = create_sixaxis_association(adapter,
> -					SIXAXIS_NAME,
> -					device_bdaddr,
> -					VENDOR, PRODUCT, SIXAXIS_PNP_RECORD);
> +	ret = create_controller_association(adapter, device_bdaddr, controller);
>  	free(device_bdaddr);
>  	free(master_bdaddr);
>  	return ret;
> @@ -424,6 +445,7 @@ static void handle_device_plug(struct udev_device *udevice)
>  	unsigned char is_usb = FALSE;
>  	int js_num = 0;
>  	int fd;
> +	struct sony_controller *controller;
>  
>  	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
>  								"hid", NULL);
> @@ -439,6 +461,8 @@ static void handle_device_plug(struct udev_device *udevice)
>  	if (!is_sixaxis(hid_name))
>  		return;
>  
> +	controller = &controllers[0];
> +

I'd expect the part above to have a for loop checking over all the
entries in the controller array instead of hard-coding to the first one.
With only one right now, of course it works, but making it a loop now
would make it trivial to add the second device (PSMove?) in the future.

>  	DBG("Found a Sixaxis device");
>  
>  	hidraw_node = udev_device_get_devnode(udevice);
> @@ -507,7 +531,7 @@ static void handle_device_plug(struct udev_device *udevice)
>  			DBG("No adapters, exiting");
>  			return;
>  		}
> -		sixpair(fd, adapter);
> +		controller_pair(fd, adapter, controller);
>  	}
>  
>  	if (js_num > 0) {

Hey, looks good overall. I like it. It seems much cleaner.

Alan.


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Antonio Ospite Aug. 19, 2011, 7:14 p.m. UTC | #2
On Thu, 18 Aug 2011 11:26:38 -0400
Alan Ott <alan@signal11.us> wrote:

> On 08/18/2011 10:22 AM, Antonio Ospite wrote:
> > Remove hardcoded #defines and put the values in a struct so we can handle 
> > different device types.
> >
> > From the USB dumps I've seen[1], different devices have just different ways to 
> > get and set the bdaddrs, the pairing algorithm is the same.
> >
> > [1] http://ps3.jim.sh/sixaxis/dumps/ 
> >
> > ---
> >  plugins/sixaxis.c |   80 ++++++++++++++++++++++++++++++++++------------------
> >  1 files changed, 52 insertions(+), 28 deletions(-)
> >
> > diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
> > index e08222c..608474f 100644
> > --- a/plugins/sixaxis.c
> > +++ b/plugins/sixaxis.c
> > @@ -70,12 +70,38 @@
> >  
[...]
> > +static struct sony_controller controllers[] = {
> > +	{
> > +		.vendor_id = 0x054c,
> > +		.product_id = 0x0268,
> > +		.name = "PLAYSTATION(R)3 Controller",
> > +		.pnp_record = "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800",
> > +		.hid_uuid = "00001124-0000-1000-8000-00805f9b34fb",
> 
> Where do the pnp_record and hid_uuid come from? It seems a bit odd to
> have a giant hard-coded identifier string (pnp), but I'm not an expert
> on this stuff, and I'm mostly just curious about it.
>

Bastien provided those, AFAIR PNP_RECORD is an identifier shown in the
association request when the plugin is not enabled, and it could depend
on the device.

WRT HID_UUID, maybe this is not device specific, it might just tell
"this is a HID device", I need confirmation about that so I can move the
field out of the structure.

Thanks,
   Antonio
Antonio Ospite Aug. 20, 2011, 10:11 a.m. UTC | #3
On Fri, 19 Aug 2011 22:57:35 +0200
Antonio Ospite <ospite@studenti.unina.it> wrote:

[...]
> About the PNP record, I can find some info about the "PnP Information"
> service in SDP, and I can see something with:
> 	$ sdptool records --tree <device_bdaddr>
> 
> but I don't know how to get the actual value currently used in the
> plugin.
>

The current PNP_RECORD for sixaxis:

3601920900000A000100000900013503191124090004350D350619010009001135031900 \
11090006350909656E09006A0901000900093508350619112409010009000D350F350D35 \
0619010009001335031900110901002513576972656C65737320436F6E74726F6C6C6572 \
0901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F \
6D707574657220456E7465727461696E6D656E7409020009010009020109010009020208 \
00090203082109020428010902052801090206359A35980822259405010904A101A10285 \
0175089501150026FF00810375019513150025013500450105091901291381027501950D \
0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0 \
050175089527090181027508953009019102750895300901B102C0A10285027508953009 \
01B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C00902073508 \
35060904090901000902082800090209280109020A280109020B09010009020C093E8009 \
020D280009020E2800

is just the same info as in the _first_ record shown decoded by:
	$ sdptool records --tree --raw <device_bdaddr>

which is a HumanInterfaceDeviceService record, so maybe it can even be
named HID record, not PNP...

Unless I am still missing something we need to hardcode it because we need
it _before_ the device talks SDP. I wonder if it can be retrieved via USB,
but I doubt it, maybe a trace of the _very_first_ usb connection of a
controller to a PS3 could revel something...

JFYI if we break it down and look at lib/sdp.h for the field types we can
see the structure in the record:

36 0192
09 0000
0A 00010000
09 0001
35 03
19 1124
09 0004
35 0D
35 06
19 0100
09 0011
35 03
19 0011
09 0006
35 09
09 656E
09 006A
09 0100
09 0009
35 08
35 06
19 1124
09 0100
09 000D
35 0F
35 0D
35 06
19 0100
09 0013
35 03
19 0011
09 0100
25 13 576972656C65737320436F6E74726F6C6C6572
      # String: Wireless Controller
09 0101
25 13 576972656C65737320436F6E74726F6C6C6572
      # String: Wireless Controller
09 0102
25 1B 536F6E7920436F6D707574657220456E7465727461696E6D656E74
      # String: Sony Computer Entertainment
09 0200
09 0100
09 0201
09 0100
09 0202
08 00
09 0203
08 21
09 0204
28 01
09 0205
28 01
09 0206
35 9A
35 98
08 22
25 94 05010904A101A102850175089501150026FF008103750195131500250135004501 \
      05091901291381027501950D0600FF8103150026FF0005010901A1007508950435 \
      0046FF0009300931093209358102C0050175089527090181027508953009019102 \
      750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B1 \
      02C0A10285EF750895300901B102C0C0 # HID descriptor
09 0207
35 08
35 06
09 0409
09 0100
09 0208
28 00
09 02
09 2801
09 020A
28 01
09 020B
09 0100
09 020C
09 3E80
09 020D
28 00
09 020E
28 00


Regards,
   Antonio
diff mbox

Patch

different device types.

From the USB dumps I've seen[1], different devices have just different ways to 
get and set the bdaddrs, the pairing algorithm is the same.

[1] http://ps3.jim.sh/sixaxis/dumps/ 

---
 plugins/sixaxis.c |   80 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index e08222c..608474f 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -70,12 +70,38 @@ 
 
 #define BDADDR_STR_SIZE 18 /* strlen("00:00:00:00:00:00") + 1 */
 
-/* Vendor and product ID for the Sixaxis PS3 controller */
-#define VENDOR 0x054c
-#define PRODUCT 0x0268
-#define SIXAXIS_NAME "PLAYSTATION(R)3 Controller"
-#define SIXAXIS_PNP_RECORD "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800"
-#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
+struct sony_controller {
+	uint16_t vendor_id;
+	uint16_t product_id;
+	char *name;
+	char *pnp_record;
+	char *hid_uuid;
+
+	/* device specific callbacks to get master/device bdaddr and set
+	 * master bdaddr
+	 */
+	char * (*get_device_bdaddr)(int);
+	char * (*get_master_bdaddr)(int);
+	int (*set_master_bdaddr) (int, char *);
+};
+
+static char *sixaxis_get_device_bdaddr(int fd);
+static char *sixaxis_get_master_bdaddr(int fd);
+static int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr);
+
+static struct sony_controller controllers[] = {
+	{
+		.vendor_id = 0x054c,
+		.product_id = 0x0268,
+		.name = "PLAYSTATION(R)3 Controller",
+		.pnp_record = "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800",
+		.hid_uuid = "00001124-0000-1000-8000-00805f9b34fb",
+		.get_device_bdaddr = sixaxis_get_device_bdaddr,
+		.get_master_bdaddr = sixaxis_get_master_bdaddr,
+		.set_master_bdaddr = sixaxis_set_master_bdaddr,
+	},
+};
+
 
 #define LED_1 (0x01 << 1)
 #define LED_2 (0x01 << 2)
@@ -90,12 +116,9 @@  static struct udev_monitor *monitor;
 static guint watch_id;
 
 
-static int create_sixaxis_association(struct btd_adapter *adapter,
-					const char *name,
+static int create_controller_association(struct btd_adapter *adapter,
 					const char *address,
-					guint32 vendor_id,
-					guint32 product_id,
-					const char *pnp_record)
+					struct sony_controller *controller)
 {
 	DBusConnection *conn;
 	sdp_record_t *rec;
@@ -108,15 +131,16 @@  static int create_sixaxis_association(struct btd_adapter *adapter,
 	adapter_get_address(adapter, &src);
 	ba2str(&src, srcaddr);
 
-	write_device_name(&dst, &src, (char *) name);
+	write_device_name(&dst, &src, controller->name);
 
 	/* Store the device's SDP record */
-	rec = record_from_string(pnp_record);
+	rec = record_from_string(controller->pnp_record);
 	store_record(srcaddr, address, rec);
 	sdp_record_free(rec);
 
 	/* Set the device id */
-	store_device_id(srcaddr, address, 0xffff, vendor_id, product_id, 0);
+	store_device_id(srcaddr, address, 0xffff, controller->vendor_id,
+			controller->product_id, 0);
 	/* Don't write a profile here,
 	 * it will be updated when the device connects */
 
@@ -137,8 +161,8 @@  static int create_sixaxis_association(struct btd_adapter *adapter,
 	}
 
 	device_set_temporary(device, FALSE);
-	device_set_name(device, name);
-	btd_device_add_uuid(device, HID_UUID);
+	device_set_name(device, controller->name);
+	btd_device_add_uuid(device, controller->hid_uuid);
 
 fail_device:
 	dbus_connection_unref(conn);
@@ -184,7 +208,7 @@  static int set_feature_report(int fd, uint8_t *report, int len)
 	return ret;
 }
 
-static char *get_device_bdaddr(int fd)
+static char *sixaxis_get_device_bdaddr(int fd)
 {
 	unsigned char *buf;
 	char *address;
@@ -210,7 +234,7 @@  static char *get_device_bdaddr(int fd)
 	return address;
 }
 
-static char *get_master_bdaddr(int fd)
+static char *sixaxis_get_master_bdaddr(int fd)
 {
 	unsigned char *buf;
 	char *address;
@@ -236,7 +260,7 @@  static char *get_master_bdaddr(int fd)
 	return address;
 }
 
-static int set_master_bdaddr(int fd, char *adapter_bdaddr)
+static int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr)
 {
 	uint8_t *report;
 	uint8_t addr[6];
@@ -282,7 +306,7 @@  out:
 	return ret;
 }
 
-static int sixpair(int fd, struct btd_adapter *adapter)
+static int controller_pair(int fd, struct btd_adapter *adapter, struct sony_controller *controller)
 {
 	char *device_bdaddr;
 	char *master_bdaddr;
@@ -294,7 +318,7 @@  static int sixpair(int fd, struct btd_adapter *adapter)
 	ba2str(&dst, adapter_bdaddr);
 	DBG("Adapter bdaddr %s", adapter_bdaddr);
 
-	master_bdaddr = get_master_bdaddr(fd);
+	master_bdaddr = controller->get_master_bdaddr(fd);
 	if (master_bdaddr == NULL) {
 		DBG("Failed to get the Old master Bluetooth address from the device");
 		return -EPERM;
@@ -305,7 +329,7 @@  static int sixpair(int fd, struct btd_adapter *adapter)
 	 */
 	if (g_strcmp0(master_bdaddr, adapter_bdaddr) != 0) {
 		DBG("Old master Bluetooth address was: %s", master_bdaddr);
-		ret = set_master_bdaddr(fd, adapter_bdaddr);
+		ret = controller->set_master_bdaddr(fd, adapter_bdaddr);
 		if (ret < 0) {
 			DBG("Failed to set the master Bluetooth address");
 			free(master_bdaddr);
@@ -313,7 +337,7 @@  static int sixpair(int fd, struct btd_adapter *adapter)
 		}
 	}
 
-	device_bdaddr = get_device_bdaddr(fd);
+	device_bdaddr = controller->get_device_bdaddr(fd);
 	if (device_bdaddr == NULL) {
 		DBG("Failed to get the Bluetooth address from the device");
 		free(master_bdaddr);
@@ -322,10 +346,7 @@  static int sixpair(int fd, struct btd_adapter *adapter)
 
 	DBG("Device bdaddr %s", device_bdaddr);
 
-	ret = create_sixaxis_association(adapter,
-					SIXAXIS_NAME,
-					device_bdaddr,
-					VENDOR, PRODUCT, SIXAXIS_PNP_RECORD);
+	ret = create_controller_association(adapter, device_bdaddr, controller);
 	free(device_bdaddr);
 	free(master_bdaddr);
 	return ret;
@@ -424,6 +445,7 @@  static void handle_device_plug(struct udev_device *udevice)
 	unsigned char is_usb = FALSE;
 	int js_num = 0;
 	int fd;
+	struct sony_controller *controller;
 
 	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
 								"hid", NULL);
@@ -439,6 +461,8 @@  static void handle_device_plug(struct udev_device *udevice)
 	if (!is_sixaxis(hid_name))
 		return;
 
+	controller = &controllers[0];
+
 	DBG("Found a Sixaxis device");
 
 	hidraw_node = udev_device_get_devnode(udevice);
@@ -507,7 +531,7 @@  static void handle_device_plug(struct udev_device *udevice)
 			DBG("No adapters, exiting");
 			return;
 		}
-		sixpair(fd, adapter);
+		controller_pair(fd, adapter, controller);
 	}
 
 	if (js_num > 0) {