Merge pull request #351 from lrusak/bluez

Patch bluez to enable DualShock 3 auto pairing
This commit is contained in:
Christian Hewitt 2016-05-18 17:11:29 +04:00
commit be042a7754
6 changed files with 433 additions and 0 deletions

View File

@ -0,0 +1,56 @@
From: Szymon Janc <szymon.janc@...>
Subject: [PATCH 1/5] sixaxis: Fix PID for Navigation Controller
Newsgroups: gmane.linux.bluez.kernel
Date: 2015-06-15 18:28:26 GMT (36 weeks, 4 days, 21 hours and 32 minutes ago)
Navigation Controller is using PID 0x042f over USB but PID 0x0268
(same as Dualshock 3) over BT.
---
plugins/sixaxis.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index fcc93bc..50db6c1 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -54,6 +54,7 @@ static const struct {
uint16_t vid;
uint16_t pid;
uint16_t version;
+ uint16_t bt_pid;
} devices[] = {
{
.name = "PLAYSTATION(R)3 Controller",
@@ -68,6 +69,7 @@ static const struct {
.vid = 0x054c,
.pid = 0x042f,
.version = 0x0000,
+ .bt_pid = 0x0268,
},
};
@@ -300,8 +302,19 @@ 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);
+
+ /* if device reports different pid/vid on BT prefer those over USB */
+ if (devices[index].bt_pid)
+ btd_device_set_pnpid(device, devices[index].source,
+ devices[index].vid,
+ devices[index].bt_pid,
+ devices[index].version);
+ else
+ btd_device_set_pnpid(device, devices[index].source,
+ devices[index].vid,
+ devices[index].pid,
+ devices[index].version);
+
btd_device_set_temporary(device, false);
return true;
--
2.1.4

View File

@ -0,0 +1,71 @@
From: Szymon Janc <szymon.janc@...>
Subject: [PATCH 2/5] core/device: Add support for setting SDP record
Newsgroups: gmane.linux.bluez.kernel
Date: 2015-06-15 18:28:27 GMT (36 weeks, 4 days, 21 hours and 33 minutes ago)
This allows to set SDP record for device without resolving services
over SDP. After SDP is provided profiles are probed.
---
src/device.c | 31 +++++++++++++++++++++++++++++++
src/device.h | 3 +++
2 files changed, 34 insertions(+)
diff --git a/src/device.c b/src/device.c
index 3ef0340..859aa3c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -5542,6 +5542,37 @@ static sdp_list_t *read_device_records(struct btd_device *device)
return recs;
}
+void btd_device_set_record(struct btd_device *device, const char *uuid,
+ sdp_record_t *rec)
+{
+ /* This API is only used for BR/EDR */
+ struct bearer_state *state = &device->bredr_state;
+ struct browse_req *req;
+ sdp_list_t *recs = NULL;
+
+ if (!rec)
+ return;
+
+ req = browse_request_new(device, NULL);
+ if (!req)
+ return;
+
+ recs = sdp_list_append(recs, rec);
+ update_bredr_services(req, recs);
+ sdp_list_free(recs, NULL);
+
+ device->svc_refreshed = true;
+ state->svc_resolved = true;
+
+ device_probe_profiles(device, req->profiles_added);
+
+ /* Propagate services changes */
+ g_dbus_emit_property_changed(dbus_conn, req->device->path,
+ DEVICE_INTERFACE, "UUIDs");
+
+ device_svc_resolved(device, device->bdaddr_type, 0);
+}
+
const sdp_record_t *btd_device_get_record(struct btd_device *device,
const char *uuid)
{
diff --git a/src/device.h b/src/device.h
index 1955f54..aee677a 100644
--- a/src/device.h
+++ b/src/device.h
@@ -62,6 +62,9 @@ struct device_addr_type {
int device_addr_type_cmp(gconstpointer a, gconstpointer b);
GSList *btd_device_get_uuids(struct btd_device *device);
void device_probe_profiles(struct btd_device *device, GSList *profiles);
+
+void btd_device_set_record(struct btd_device *device, const char *uuid,
+ sdp_record_t *rec);
const sdp_record_t *btd_device_get_record(struct btd_device *device,
const char *uuid);
struct gatt_primary *btd_device_get_primary(struct btd_device *device,
--
2.1.4

View File

@ -0,0 +1,216 @@
From: Szymon Janc <szymon.janc@...>
Subject: [PATCH 3/5] sixaxis: Provide DualShock 3 SDP record while adding new device
Newsgroups: gmane.linux.bluez.kernel
Date: 2015-06-15 18:28:28 GMT (36 weeks, 4 days, 21 hours and 33 minutes ago)
This allows to skip SDP search for DualShock 3 devices. Since some
DS3 clones were reported to not provide any SDP record this should
allow to operate them.
---
Makefile.plugins | 1 +
plugins/sixaxis.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 167 insertions(+)
diff --git a/Makefile.plugins b/Makefile.plugins
index cae43d9..2c2385d 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -118,4 +118,5 @@ plugins_sixaxis_la_SOURCES = plugins/sixaxis.c
plugins_sixaxis_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
-no-undefined @UDEV_LIBS@
plugins_sixaxis_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden @UDEV_CFLAGS@
+plugins_sixaxis_la_LIBADD = lib/libbluetooth-internal.la
endif
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 50db6c1..782a89f 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -40,4 +40,6 @@
#include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
#include "lib/uuid.h"
#include "src/adapter.h"
@@ -257,6 +258,170 @@ out:
return false;
}
+static sdp_record_t *get_sdp_record(void)
+{
+ sdp_record_t *record;
+ uint16_t hid_release, hid_parser, version, timeout;
+ uint8_t sdp_disable, battery, remote_wakeup, norm_connect, boot_device;
+ uint8_t subclass, country, virtual_cable, reconnect;
+ sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+ uuid_t root_uuid, hidkb_uuid, l2cap_uuid, hidp_uuid;
+ sdp_profile_desc_t profile;
+ sdp_list_t *aproto, *proto[3];
+ sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2;
+ uint8_t dtd = SDP_UINT16;
+ uint8_t dtd2 = SDP_UINT8;
+ uint8_t dtd_data = SDP_TEXT_STR8;
+ void *dtds[2];
+ void *values[2];
+ void *dtds2[2];
+ void *values2[2];
+ int leng[2];
+ uint8_t hid_spec_type = 0x22;
+ uint16_t hid_attr_lang[] = { 0x409, 0x100 };
+ static const uint16_t ctrl = 0x11;
+ static const uint16_t intr = 0x13;
+ uint8_t hid_spec[] = {
+ 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 0x85, 0x01,
+ 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 0x26, 0xff, 0x00, 0x81,
+ 0x03, 0x75, 0x01, 0x95, 0x13, 0x15, 0x00, 0x25, 0x01, 0x35,
+ 0x00, 0x45, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
+ 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 0x81, 0x03,
+ 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 0x01, 0x09, 0x01, 0xa1,
+ 0x00, 0x75, 0x08, 0x95, 0x04, 0x35, 0x00, 0x46, 0xff, 0x00,
+ 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
+ 0xc0, 0x05, 0x01, 0x75, 0x08, 0x95, 0x27, 0x09, 0x01, 0x81,
+ 0x02, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0x91, 0x02, 0x75,
+ 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
+ 0x85, 0x02, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
+ 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 0x30, 0x09,
+ 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0xef, 0x75, 0x08,
+ 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xc0, 0x00
+ };
+
+ record = sdp_record_alloc();
+ if (!record)
+ return NULL;
+
+ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+ root = sdp_list_append(0, &root_uuid);
+ sdp_set_browse_groups(record, root);
+
+ sdp_add_lang_attr(record);
+
+ sdp_uuid16_create(&hidkb_uuid, HID_SVCLASS_ID);
+ svclass_id = sdp_list_append(0, &hidkb_uuid);
+ sdp_set_service_classes(record, svclass_id);
+
+ sdp_uuid16_create(&profile.uuid, HID_PROFILE_ID);
+ profile.version = 0x0100;
+ pfseq = sdp_list_append(0, &profile);
+ sdp_set_profile_descs(record, pfseq);
+
+ /* protocols */
+ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+ proto[1] = sdp_list_append(0, &l2cap_uuid);
+ psm = sdp_data_alloc(SDP_UINT16, &ctrl);
+ proto[1] = sdp_list_append(proto[1], psm);
+ apseq = sdp_list_append(0, proto[1]);
+
+ sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
+ proto[2] = sdp_list_append(0, &hidp_uuid);
+ apseq = sdp_list_append(apseq, proto[2]);
+
+ aproto = sdp_list_append(0, apseq);
+ sdp_set_access_protos(record, aproto);
+
+ /* additional protocols */
+ proto[1] = sdp_list_append(0, &l2cap_uuid);
+ psm = sdp_data_alloc(SDP_UINT16, &intr);
+ proto[1] = sdp_list_append(proto[1], psm);
+ apseq = sdp_list_append(0, proto[1]);
+
+ sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
+ proto[2] = sdp_list_append(0, &hidp_uuid);
+ apseq = sdp_list_append(apseq, proto[2]);
+
+ aproto = sdp_list_append(0, apseq);
+ sdp_set_add_access_protos(record, aproto);
+
+ sdp_set_info_attr(record, "Wireless Controller",
+ "Sony Computer Entertainment",
+ "Wireless Controller");
+
+ hid_release = 0x0100;
+ sdp_attr_add_new(record, SDP_ATTR_HID_DEVICE_RELEASE_NUMBER, SDP_UINT16,
+ &hid_release);
+
+ hid_parser = 0x0100;
+ sdp_attr_add_new(record, SDP_ATTR_HID_PARSER_VERSION, SDP_UINT16,
+ &hid_parser);
+
+ subclass = 0x00;
+ sdp_attr_add_new(record, SDP_ATTR_HID_DEVICE_SUBCLASS, SDP_UINT8,
+ &subclass);
+
+ country = 0x21;
+ sdp_attr_add_new(record, SDP_ATTR_HID_COUNTRY_CODE, SDP_UINT8,
+ &country);
+
+ virtual_cable = 0x01;
+ sdp_attr_add_new(record, SDP_ATTR_HID_VIRTUAL_CABLE, SDP_BOOL,
+ &virtual_cable);
+
+ reconnect = 0x01;
+ sdp_attr_add_new(record, SDP_ATTR_HID_RECONNECT_INITIATE, SDP_BOOL,
+ &reconnect);
+
+ dtds[0] = &dtd2;
+ values[0] = &hid_spec_type;
+ dtds[1] = &dtd_data;
+ values[1] = hid_spec;
+ leng[0] = 0;
+ leng[1] = sizeof(hid_spec);
+ hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2);
+ hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst);
+ sdp_attr_add(record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2);
+
+ dtds2[0] = &dtd;
+ values2[0] = &hid_attr_lang[0];
+ dtds2[1] = &dtd;
+ values2[1] = &hid_attr_lang[1];
+ lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2);
+ lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst);
+ sdp_attr_add(record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2);
+
+ sdp_disable = 0x00;
+ sdp_attr_add_new(record, SDP_ATTR_HID_SDP_DISABLE, SDP_BOOL,
+ &sdp_disable);
+
+ battery = 0x01;
+ sdp_attr_add_new(record, SDP_ATTR_HID_BATTERY_POWER, SDP_BOOL,
+ &battery);
+
+ remote_wakeup = 0x01;
+ sdp_attr_add_new(record, SDP_ATTR_HID_REMOTE_WAKEUP, SDP_BOOL,
+ &remote_wakeup);
+
+ version = 0x0100;
+ sdp_attr_add_new(record, SDP_ATTR_HID_PROFILE_VERSION, SDP_UINT16,
+ &version);
+
+ timeout = 0x3e80;
+ sdp_attr_add_new(record, SDP_ATTR_HID_SUPERVISION_TIMEOUT, SDP_UINT16,
+ &timeout);
+
+ norm_connect = 0x00;
+ sdp_attr_add_new(record, SDP_ATTR_HID_NORMALLY_CONNECTABLE, SDP_BOOL,
+ &norm_connect);
+
+ boot_device = 0x00;
+ sdp_attr_add_new(record, SDP_ATTR_HID_BOOT_DEVICE, SDP_BOOL,
+ &boot_device);
+
+ return record;
+}
+
static bool setup_device(int fd, int index, struct btd_adapter *adapter)
{
char device_addr[18], master_addr[18], adapter_addr[18];
@@ -316,6 +481,7 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
devices[index].version);
btd_device_set_temporary(device, false);
+ btd_device_set_record(device, HID_UUID, get_sdp_record());
return true;
}
--
2.1.4

View File

@ -0,0 +1,36 @@
From: Szymon Janc <szymon.janc@...>
Subject: [PATCH 4/5] profiles/input: Remove not needed sixaxis checks
Newsgroups: gmane.linux.bluez.kernel
Date: 2015-06-15 18:28:29 GMT (36 weeks, 4 days, 21 hours and 33 minutes ago)
This check is now needed only for DualShock 4.
---
profiles/input/server.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/profiles/input/server.c b/profiles/input/server.c
index eb3fcf8..101108b 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -131,18 +131,10 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
vid = btd_device_get_vendor(device);
pid = btd_device_get_product(device);
- /* DualShock 3 */
- if (vid == 0x054c && pid == 0x0268)
- return true;
-
/* DualShock 4 */
if (vid == 0x054c && pid == 0x05c4)
return true;
- /* Navigation Controller */
- if (vid == 0x054c && pid == 0x042f)
- return true;
-
return false;
}
--
2.1.4

View File

@ -0,0 +1,43 @@
From: Szymon Janc <szymon.janc@...>
Subject: [PATCH 5/5] sixaxis: Fix multi-line comments style
Newsgroups: gmane.linux.bluez.kernel
Date: 2015-06-15 18:28:30 GMT (36 weeks, 4 days, 21 hours and 33 minutes ago)
---
plugins/sixaxis.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 782a89f..9b6cad4 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -435,9 +435,11 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
if (get_master_bdaddr(fd, &master_bdaddr) < 0)
return false;
- /* This can happen if controller was plugged while already connected
+ /*
+ * This can happen if controller was plugged while already connected
* eg. to charge up battery.
- * Don't set LEDs in that case, hence return false */
+ * Don't set LEDs in that case, hence return false
+ */
device = btd_adapter_find_device(adapter, &device_bdaddr,
BDADDR_BREDR);
if (device && btd_device_is_connected(device))
@@ -533,8 +535,10 @@ static int get_js_number(struct udev_device *udevice)
if (!input_parent)
goto next;
- /* check if this is the joystick relative to the hidraw device
- * above */
+ /*
+ * check if this is the joystick relative to the hidraw device
+ * above
+ */
input_id = udev_device_get_sysattr_value(input_parent, "uniq");
/*
--
2.1.4

View File

@ -0,0 +1,11 @@
diff -Naur bluez-5.37/plugins/sixaxis.c bluez-5.37.patch/plugins/sixaxis.c
--- bluez-5.37/plugins/sixaxis.c 2016-04-21 21:38:45.805962009 +0200
+++ bluez-5.37.patch/plugins/sixaxis.c 2016-04-24 15:22:36.852107941 +0200
@@ -484,6 +484,7 @@
devices[index].version);
btd_device_set_temporary(device, false);
+ btd_device_set_trusted(device, true);
btd_device_set_record(device, HID_UUID, get_sdp_record());
return true;