diff --git a/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch b/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch deleted file mode 100644 index 1ea3e6f..0000000 --- a/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 3027cb7141fb65cf3eeda69c688db8c4045e2d3f Mon Sep 17 00:00:00 2001 -From: Giovanni Campagna -Date: Sat, 12 Oct 2013 17:45:25 +0200 -Subject: [PATCH] Allow using obexd without systemd in the user session - -Not all sessions run systemd --user (actually, the majority -doesn't), so the dbus daemon must be able to spawn obexd -directly, and to do so it needs the full path of the daemon. ---- - Makefile.obexd | 4 ++-- - obexd/src/org.bluez.obex.service | 4 ---- - obexd/src/org.bluez.obex.service.in | 4 ++++ - 3 files changed, 6 insertions(+), 6 deletions(-) - delete mode 100644 obexd/src/org.bluez.obex.service - create mode 100644 obexd/src/org.bluez.obex.service.in - -diff --git a/Makefile.obexd b/Makefile.obexd -index 3760867..142e7c3 100644 ---- a/Makefile.obexd -+++ b/Makefile.obexd -@@ -2,12 +2,12 @@ - if SYSTEMD - systemduserunitdir = @SYSTEMD_USERUNITDIR@ - systemduserunit_DATA = obexd/src/obex.service -+endif - - dbussessionbusdir = @DBUS_SESSIONBUSDIR@ - dbussessionbus_DATA = obexd/src/org.bluez.obex.service --endif - --EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service -+EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service.in - - obex_plugindir = $(libdir)/obex/plugins - -diff --git a/obexd/src/org.bluez.obex.service b/obexd/src/org.bluez.obex.service -deleted file mode 100644 -index a538088..0000000 ---- a/obexd/src/org.bluez.obex.service -+++ /dev/null -@@ -1,4 +0,0 @@ --[D-BUS Service] --Name=org.bluez.obex --Exec=/bin/false --SystemdService=dbus-org.bluez.obex.service -diff --git a/obexd/src/org.bluez.obex.service.in b/obexd/src/org.bluez.obex.service.in -new file mode 100644 -index 0000000..9c815f2 ---- /dev/null -+++ b/obexd/src/org.bluez.obex.service.in -@@ -0,0 +1,4 @@ -+[D-BUS Service] -+Name=org.bluez.obex -+Exec=@libexecdir@/obexd -+SystemdService=dbus-org.bluez.obex.service --- -1.8.3.1 - diff --git a/0001-autopair-Don-t-handle-the-iCade.patch b/0001-autopair-Don-t-handle-the-iCade.patch new file mode 100644 index 0000000..7c9e658 --- /dev/null +++ b/0001-autopair-Don-t-handle-the-iCade.patch @@ -0,0 +1,48 @@ +From 8c23335a00bbd6f359702024698a24d45e3c653b Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 19 Nov 2013 14:11:39 +0100 +Subject: [PATCH] autopair: Don't handle the iCade + +We can't easily enter digits other than 1 through 4 (inclusive) +so leave it up to the agent to figure out a good passcode +for the iCade. + +Note that we can not use the VID/PID of the device, as it is not +yet known at that point. +--- + plugins/autopair.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/plugins/autopair.c b/plugins/autopair.c +index d44cf539b..a9d2a930a 100644 +--- a/plugins/autopair.c ++++ b/plugins/autopair.c +@@ -60,13 +60,24 @@ static ssize_t autopair_pincb(struct btd_adapter *adapter, + { + char addr[18]; + char pinstr[7]; ++ char name[25]; + uint32_t class; + + ba2str(device_get_address(device), addr); + + class = btd_device_get_class(device); + +- DBG("device %s 0x%x", addr, class); ++ device_get_name(device, name, sizeof(name)); ++ name[sizeof(name) - 1] = 0; ++ ++ DBG("device '%s' (%s) class: 0x%x vid/pid: 0x%X/0x%X", ++ name, addr, class, ++ btd_device_get_vendor (device), ++ btd_device_get_product (device)); ++ ++ /* The iCade shouldn't use random PINs like normal keyboards */ ++ if (name != NULL && strstr(name, "iCade") != NULL) ++ return 0; + + /* This is a class-based pincode guesser. Ignore devices with an + * unknown class. +-- +2.14.1 + diff --git a/0001-build-Enable-BIND_NOW.patch b/0001-build-Enable-BIND_NOW.patch new file mode 100644 index 0000000..b7c7e57 --- /dev/null +++ b/0001-build-Enable-BIND_NOW.patch @@ -0,0 +1,31 @@ +From e45c8fdcb3d7cdb654f6819c02d1bbb5b40b6116 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 7 Nov 2013 09:23:35 +0100 +Subject: [PATCH 1/4] build: Enable BIND_NOW + +Partial RELRO means that the object is GNU_RELRO but not BIND_NOW. This +reduces the effectiveness of RELRO. bluez triggers this because it +enables PIE during the build, and rpmdiff takes this as an indicator +that the best possible hardening is desired. + +https://bugzilla.redhat.com/show_bug.cgi?id=983161 +--- + acinclude.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index bc39c6d73..efce2f3cb 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -50,7 +50,7 @@ AC_DEFUN([MISC_FLAGS], [ + if (test "${enableval}" = "yes" && + test "${ac_cv_prog_cc_pie}" = "yes"); then + misc_cflags="$misc_cflags -fPIC" +- misc_ldflags="$misc_ldflags -pie" ++ misc_ldflags="$misc_ldflags -pie -Wl,-z,now" + fi + ]) + if (test "$enable_coverage" = "yes"); then +-- +2.14.1 + diff --git a/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch b/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch index 004a389..f79d3ad 100644 --- a/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch +++ b/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch @@ -1,7 +1,7 @@ -From f7861d27fbcbc519f57d8496aa9486f487908821 Mon Sep 17 00:00:00 2001 +From 90b72b787a6ae6b9b0bf8ece238e108e8607a433 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 9 Nov 2013 18:13:43 +0100 -Subject: [PATCH 1/5] obex: Use GLib helper function to manipulate paths +Subject: [PATCH 1/2] obex: Use GLib helper function to manipulate paths Instead of trying to do it by hand. This also makes sure that relative paths aren't used by the agent. @@ -10,10 +10,10 @@ relative paths aren't used by the agent. 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/obexd/src/manager.c b/obexd/src/manager.c -index cec8a39..f18896e 100644 +index f84384ae4..285c07c37 100644 --- a/obexd/src/manager.c +++ b/obexd/src/manager.c -@@ -651,14 +651,14 @@ static void agent_reply(DBusPendingCall *call, void *user_data) +@@ -650,14 +650,14 @@ static void agent_reply(DBusPendingCall *call, void *user_data) DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { /* Splits folder and name */ @@ -34,5 +34,5 @@ index cec8a39..f18896e 100644 } -- -1.8.4.2 +2.14.1 diff --git a/0001-plugins-sixaxis-Remove-LEDs-handling.patch b/0001-plugins-sixaxis-Remove-LEDs-handling.patch new file mode 100644 index 0000000..3603ed4 --- /dev/null +++ b/0001-plugins-sixaxis-Remove-LEDs-handling.patch @@ -0,0 +1,362 @@ +From 94149e19844c3344d1cdd57c24676a0c96b9c8a1 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 25 Aug 2017 19:59:20 +0200 +Subject: [PATCH 1/9] plugins/sixaxis: Remove LEDs handling + +It's done in the kernel since 2014 in linux kernel commit +8025087acf9d2b941bae93b3e0967560e7e03e87 +--- + plugins/sixaxis.c | 295 +----------------------------------------------------- + 1 file changed, 5 insertions(+), 290 deletions(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index 7e3c950b4..7d3a8f3ac 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -71,17 +71,6 @@ static const struct { + }, + }; + +-struct leds_data { +- char *syspath_prefix; +- uint8_t bitmap; +-}; +- +-static void leds_data_destroy(struct leds_data *data) +-{ +- free(data->syspath_prefix); +- free(data); +-} +- + static struct udev *ctx = NULL; + static struct udev_monitor *monitor = NULL; + static guint watch_id = 0; +@@ -146,115 +135,6 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr) + return ret; + } + +-static uint8_t calc_leds_bitmap(int number) +-{ +- uint8_t bitmap = 0; +- +- /* TODO we could support up to 10 (1 + 2 + 3 + 4) */ +- if (number > 7) +- return bitmap; +- +- if (number > 4) { +- bitmap |= 0x10; +- number -= 4; +- } +- +- bitmap |= 0x01 << number; +- +- return bitmap; +-} +- +-static void set_leds_hidraw(int fd, uint8_t leds_bitmap) +-{ +- /* +- * the total time the led is active (0xff means forever) +- * | duty_length: cycle time in deciseconds (0 - "blink very fast") +- * | | ??? (Maybe a phase shift or duty_length multiplier?) +- * | | | % of duty_length led is off (0xff means 100%) +- * | | | | % of duty_length led is on (0xff means 100%) +- * | | | | | +- * 0xff, 0x27, 0x10, 0x00, 0x32, +- */ +- uint8_t leds_report[] = { +- 0x01, +- 0x00, 0x00, 0x00, 0x00, 0x00, /* rumble values TBD */ +- 0x00, 0x00, 0x00, 0x00, 0x00, /* LED_1=0x02, LED_2=0x04 ... */ +- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */ +- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */ +- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */ +- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */ +- 0x00, 0x00, 0x00, 0x00, 0x00, +- }; +- int ret; +- +- leds_report[10] = leds_bitmap; +- +- ret = write(fd, leds_report, sizeof(leds_report)); +- if (ret == sizeof(leds_report)) +- return; +- +- if (ret < 0) +- error("sixaxis: failed to set LEDS (%s)", strerror(errno)); +- else +- error("sixaxis: failed to set LEDS (%d bytes written)", ret); +-} +- +-static bool set_leds_sysfs(struct leds_data *data) +-{ +- int i; +- +- if (!data->syspath_prefix) +- return false; +- +- /* start from 1, LED0 is never used */ +- for (i = 1; i <= 4; i++) { +- char path[PATH_MAX] = { 0 }; +- char buf[2] = { 0 }; +- int fd; +- int ret; +- +- snprintf(path, PATH_MAX, "%s%d/brightness", +- data->syspath_prefix, i); +- +- fd = open(path, O_WRONLY); +- if (fd < 0) { +- error("sixaxis: cannot open %s (%s)", path, +- strerror(errno)); +- return false; +- } +- +- buf[0] = '0' + !!(data->bitmap & (1 << i)); +- ret = write(fd, buf, sizeof(buf)); +- close(fd); +- if (ret != sizeof(buf)) +- return false; +- } +- +- return true; +-} +- +-static gboolean setup_leds(GIOChannel *channel, GIOCondition cond, +- gpointer user_data) +-{ +- struct leds_data *data = user_data; +- +- if (!data) +- return FALSE; +- +- if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) +- goto out; +- +- if(!set_leds_sysfs(data)) { +- int fd = g_io_channel_unix_get_fd(channel); +- set_leds_hidraw(fd, data->bitmap); +- } +- +-out: +- leds_data_destroy(data); +- +- return FALSE; +-} +- + static bool setup_device(int fd, int index, struct btd_adapter *adapter) + { + char device_addr[18], master_addr[18], adapter_addr[18]; +@@ -269,8 +149,7 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter) + return false; + + /* 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 */ ++ * eg. to charge up battery. */ + device = btd_adapter_find_device(adapter, &device_bdaddr, + BDADDR_BREDR); + if (device && btd_device_is_connected(device)) +@@ -307,152 +186,6 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter) + return true; + } + +-static int get_js_number(struct udev_device *udevice) +-{ +- struct udev_list_entry *devices, *dev_list_entry; +- struct udev_enumerate *enumerate; +- struct udev_device *hid_parent; +- const char *hidraw_node; +- const char *hid_id; +- int number = 0; +- +- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice, +- "hid", NULL); +- +- /* +- * Look for HID_UNIQ first for the correct behavior via BT, if +- * HID_UNIQ is not available it means the USB bus is being used and we +- * can rely on HID_PHYS. +- */ +- hid_id = udev_device_get_property_value(hid_parent, "HID_UNIQ"); +- if (!hid_id) +- hid_id = udev_device_get_property_value(hid_parent, +- "HID_PHYS"); +- +- hidraw_node = udev_device_get_devnode(udevice); +- if (!hid_id || !hidraw_node) +- return 0; +- +- enumerate = udev_enumerate_new(udev_device_get_udev(udevice)); +- udev_enumerate_add_match_sysname(enumerate, "js*"); +- udev_enumerate_scan_devices(enumerate); +- devices = udev_enumerate_get_list_entry(enumerate); +- +- udev_list_entry_foreach(dev_list_entry, devices) { +- struct udev_device *input_parent; +- struct udev_device *js_dev; +- const char *input_id; +- const char *devname; +- +- devname = udev_list_entry_get_name(dev_list_entry); +- js_dev = udev_device_new_from_syspath( +- udev_device_get_udev(udevice), +- devname); +- +- input_parent = udev_device_get_parent_with_subsystem_devtype( +- js_dev, "input", NULL); +- if (!input_parent) +- goto next; +- +- /* check if this is the joystick relative to the hidraw device +- * above */ +- input_id = udev_device_get_sysattr_value(input_parent, "uniq"); +- +- /* +- * A strlen() check is needed because input device over USB +- * have the UNIQ attribute defined but with an empty value. +- */ +- if (!input_id || strlen(input_id) == 0) +- input_id = udev_device_get_sysattr_value(input_parent, +- "phys"); +- +- if (!input_id) +- goto next; +- +- if (!strcmp(input_id, hid_id)) { +- number = atoi(udev_device_get_sysnum(js_dev)); +- +- /* joystick numbers start from 0, leds from 1 */ +- number++; +- +- udev_device_unref(js_dev); +- break; +- } +-next: +- udev_device_unref(js_dev); +- } +- +- udev_enumerate_unref(enumerate); +- +- return number; +-} +- +-static char *get_leds_syspath_prefix(struct udev_device *udevice) +-{ +- struct udev_list_entry *dev_list_entry; +- struct udev_enumerate *enumerate; +- struct udev_device *hid_parent; +- const char *syspath; +- char *syspath_prefix; +- +- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice, +- "hid", NULL); +- +- enumerate = udev_enumerate_new(udev_device_get_udev(udevice)); +- udev_enumerate_add_match_parent(enumerate, hid_parent); +- udev_enumerate_add_match_subsystem(enumerate, "leds"); +- udev_enumerate_scan_devices(enumerate); +- +- dev_list_entry = udev_enumerate_get_list_entry(enumerate); +- if (!dev_list_entry) { +- syspath_prefix = NULL; +- goto out; +- } +- +- syspath = udev_list_entry_get_name(dev_list_entry); +- +- /* +- * All the sysfs paths of the LEDs have the same structure, just the +- * number changes, so strip it and store only the common prefix. +- * +- * Subtracting 1 here means assuming that the LED number is a single +- * digit, this is safe as the kernel driver only exposes 4 LEDs. +- */ +- syspath_prefix = strndup(syspath, strlen(syspath) - 1); +- +-out: +- udev_enumerate_unref(enumerate); +- +- return syspath_prefix; +-} +- +-static struct leds_data *get_leds_data(struct udev_device *udevice) +-{ +- struct leds_data *data; +- int number; +- +- number = get_js_number(udevice); +- DBG("number %d", number); +- +- data = malloc0(sizeof(*data)); +- if (!data) +- return NULL; +- +- data->bitmap = calc_leds_bitmap(number); +- if (data->bitmap == 0) { +- leds_data_destroy(data); +- return NULL; +- } +- +- /* +- * It's OK if this fails, set_leds_hidraw() will be used in +- * case data->syspath_prefix is NULL. +- */ +- data->syspath_prefix = get_leds_syspath_prefix(udevice); +- +- return data; +-} +- + static int get_supported_device(struct udev_device *udevice, uint16_t *bus) + { + struct udev_device *hid_parent; +@@ -481,7 +214,6 @@ static int get_supported_device(struct udev_device *udevice, uint16_t *bus) + static void device_added(struct udev_device *udevice) + { + struct btd_adapter *adapter; +- GIOChannel *io; + uint16_t bus; + int index; + int fd; +@@ -493,6 +225,8 @@ static void device_added(struct udev_device *udevice) + index = get_supported_device(udevice, &bus); + if (index < 0) + return; ++ if (bus != BUS_USB) ++ return; + + info("sixaxis: compatible device connected: %s (%04X:%04X)", + devices[index].name, devices[index].vid, +@@ -502,27 +236,8 @@ static void device_added(struct udev_device *udevice) + if (fd < 0) + return; + +- io = g_io_channel_unix_new(fd); +- +- switch (bus) { +- case BUS_USB: +- if (!setup_device(fd, index, adapter)) +- break; +- +- /* fall through */ +- case BUS_BLUETOOTH: +- /* wait for events before setting leds */ +- g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, +- setup_leds, get_leds_data(udevice)); +- +- break; +- default: +- DBG("uknown bus type (%u)", bus); +- break; +- } +- +- g_io_channel_set_close_on_unref(io, TRUE); +- g_io_channel_unref(io); ++ setup_device(fd, index, adapter); ++ close(fd); + } + + static gboolean monitor_watch(GIOChannel *source, GIOCondition condition, +-- +2.14.1 + diff --git a/0001-plugins-sixaxis-Use-the-same-device-name-as-the-kern.patch b/0001-plugins-sixaxis-Use-the-same-device-name-as-the-kern.patch new file mode 100644 index 0000000..38298dc --- /dev/null +++ b/0001-plugins-sixaxis-Use-the-same-device-name-as-the-kern.patch @@ -0,0 +1,29 @@ +From 7cdfddada0609d0df5cfe3fe3a2fba6355e53d26 Mon Sep 17 00:00:00 2001 +From: Nicolas Werner +Date: Tue, 8 Aug 2017 00:48:33 +0200 +Subject: [PATCH] plugins/sixaxis: Use the same device name as the kernel + +Some games check the device name to recognize a playstation controller. +This changes the device name, when using a PS3 controller over +bluetooth, to match the device name, that is advertised when using the +controller via USB. +--- + plugins/sixaxis.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index fcc93bc60..7e3c950b4 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -56,7 +56,7 @@ static const struct { + uint16_t version; + } devices[] = { + { +- .name = "PLAYSTATION(R)3 Controller", ++ .name = "Sony PLAYSTATION(R)3 Controller", + .source = 0x0002, + .vid = 0x054c, + .pid = 0x0268, +-- +2.14.1 + diff --git a/0002-adapter-Add-btd_request_authorization_cable_configur.patch b/0002-adapter-Add-btd_request_authorization_cable_configur.patch new file mode 100644 index 0000000..96628b8 --- /dev/null +++ b/0002-adapter-Add-btd_request_authorization_cable_configur.patch @@ -0,0 +1,147 @@ +From 61ca4a50c8d03b00e6cb00ac6f6fee64fa310ff5 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 7 Jul 2015 15:45:26 +0200 +Subject: [PATCH 2/9] adapter: Add btd_request_authorization_cable_configured() + +Add btd_request_authorization_cable_configured() function to allow +cable configured devices to ask the user straight away about whether the +device should be allowed to connect to the computer. + +This allows us to ask the user at the time of the USB connection and +initial setup, rather than when the first Bluetooth connection is made. + +The fact that the device might not be connected to the adapter when +this event is triggered is mentioned in the Agent API docs. +--- + doc/agent-api.txt | 5 ++++- + src/adapter.c | 42 ++++++++++++++++++++++++++++++++++++------ + src/adapter.h | 2 ++ + 3 files changed, 42 insertions(+), 7 deletions(-) + +diff --git a/doc/agent-api.txt b/doc/agent-api.txt +index 801ccb665..0d9347cab 100644 +--- a/doc/agent-api.txt ++++ b/doc/agent-api.txt +@@ -163,7 +163,10 @@ Methods void Release() + This method gets called to request the user to + authorize an incoming pairing attempt which + would in other circumstances trigger the just-works +- model. ++ model, or when the user plugged in a device that ++ implements cable pairing. In the latter case, the ++ device would not be connected to the adapter via ++ Bluetooth yet. + + Possible errors: org.bluez.Error.Rejected + org.bluez.Error.Canceled +diff --git a/src/adapter.c b/src/adapter.c +index a571b1870..b24b73e30 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -265,6 +265,11 @@ struct btd_adapter { + bool is_default; /* true if adapter is default one */ + }; + ++typedef enum { ++ ADAPTER_AUTHORIZE_DISCONNECTED = 0, ++ ADAPTER_AUTHORIZE_CHECK_CONNECTED ++} adapter_authorize_type; ++ + static struct btd_adapter *btd_adapter_lookup(uint16_t index) + { + GList *list; +@@ -6088,8 +6093,9 @@ static void svc_complete(struct btd_device *dev, int err, void *user_data) + } + + static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst, +- const char *uuid, service_auth_cb cb, +- void *user_data) ++ const char *uuid, ++ adapter_authorize_type check_for_connection, ++ service_auth_cb cb, void *user_data) + { + struct service_auth *auth; + struct btd_device *device; +@@ -6105,7 +6111,7 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst, + } + + /* Device connected? */ +- if (!g_slist_find(adapter->connections, device)) ++ if (check_for_connection && !g_slist_find(adapter->connections, device)) + btd_error(adapter->dev_id, + "Authorization request for non-connected device!?"); + +@@ -6119,7 +6125,12 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst, + auth->device = device; + auth->adapter = adapter; + auth->id = ++id; +- auth->svc_id = device_wait_for_svc_complete(device, svc_complete, auth); ++ if (check_for_connection) ++ auth->svc_id = device_wait_for_svc_complete(device, svc_complete, auth); ++ else { ++ if (adapter->auth_idle_id == 0) ++ adapter->auth_idle_id = g_idle_add(process_auth_queue, adapter); ++ } + + g_queue_push_tail(adapter->auths, auth); + +@@ -6138,7 +6149,8 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst, + if (!adapter) + return 0; + +- return adapter_authorize(adapter, dst, uuid, cb, user_data); ++ return adapter_authorize(adapter, dst, uuid, ++ ADAPTER_AUTHORIZE_CHECK_CONNECTED, cb, user_data); + } + + for (l = adapters; l != NULL; l = g_slist_next(l)) { +@@ -6146,7 +6158,8 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst, + + adapter = l->data; + +- id = adapter_authorize(adapter, dst, uuid, cb, user_data); ++ id = adapter_authorize(adapter, dst, uuid, ++ ADAPTER_AUTHORIZE_CHECK_CONNECTED, cb, user_data); + if (id != 0) + return id; + } +@@ -6154,6 +6167,23 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst, + return 0; + } + ++guint btd_request_authorization_cable_configured(const bdaddr_t *src, const bdaddr_t *dst, ++ const char *uuid, service_auth_cb cb, ++ void *user_data) ++{ ++ struct btd_adapter *adapter; ++ ++ if (bacmp(src, BDADDR_ANY) == 0) ++ return 0; ++ ++ adapter = adapter_find(src); ++ if (!adapter) ++ return 0; ++ ++ return adapter_authorize(adapter, dst, uuid, ++ ADAPTER_AUTHORIZE_DISCONNECTED, cb, user_data); ++} ++ + static struct service_auth *find_authorization(guint id) + { + GSList *l; +diff --git a/src/adapter.h b/src/adapter.h +index f9178d59e..a85327cd1 100644 +--- a/src/adapter.h ++++ b/src/adapter.h +@@ -120,6 +120,8 @@ int btd_register_adapter_driver(struct btd_adapter_driver *driver); + void btd_unregister_adapter_driver(struct btd_adapter_driver *driver); + guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst, + const char *uuid, service_auth_cb cb, void *user_data); ++guint btd_request_authorization_cable_configured(const bdaddr_t *src, const bdaddr_t *dst, ++ const char *uuid, service_auth_cb cb, void *user_data); + int btd_cancel_authorization(guint id); + + int btd_adapter_restore_powered(struct btd_adapter *adapter); +-- +2.14.1 + diff --git a/0002-autopair-Don-t-handle-the-iCade.patch b/0002-autopair-Don-t-handle-the-iCade.patch deleted file mode 100644 index 68751ae..0000000 --- a/0002-autopair-Don-t-handle-the-iCade.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c16ae7041c7511d8d1ed8441f696716fa6a9117e Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Tue, 19 Nov 2013 14:11:39 +0100 -Subject: [PATCH 2/5] autopair: Don't handle the iCade - -We can't easily enter digits other than 1 through 4 (inclusive) -so leave it up to the agent to figure out a good passcode -for the iCade. - -Note that we can not use the VID/PID of the device, as it is not -yet known at that point. ---- - plugins/autopair.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/plugins/autopair.c b/plugins/autopair.c -index 8c98c12..5d2f6f7 100644 ---- a/plugins/autopair.c -+++ b/plugins/autopair.c -@@ -57,13 +57,23 @@ static ssize_t autopair_pincb(struct btd_adapter *adapter, - { - char addr[18]; - char pinstr[7]; -+ char name[25]; - uint32_t class; - - ba2str(device_get_address(device), addr); - - class = btd_device_get_class(device); - -- DBG("device %s 0x%x", addr, class); -+ device_get_name(device, name, sizeof(name)); -+ name[sizeof(name) - 1] = 0; -+ -+ DBG("device %s (%s) 0x%x", addr, name, class); -+ -+ g_message ("vendor 0x%X product: 0x%X", btd_device_get_vendor (device), btd_device_get_product (device)); -+ -+ /* The iCade shouldn't use random PINs like normal keyboards */ -+ if (name != NULL && strstr(name, "iCade") != NULL) -+ return 0; - - /* This is a class-based pincode guesser. Ignore devices with an - * unknown class. --- -1.8.4.2 - diff --git a/0002-obex-Allow-using-obexd-w-o-systemd-user-session.patch b/0002-obex-Allow-using-obexd-w-o-systemd-user-session.patch new file mode 100644 index 0000000..beef88b --- /dev/null +++ b/0002-obex-Allow-using-obexd-w-o-systemd-user-session.patch @@ -0,0 +1,49 @@ +From 0f8d9e85f264f653fc255fabc06eb5b5c9f9f1e6 Mon Sep 17 00:00:00 2001 +From: Giovanni Campagna +Date: Sat, 12 Oct 2013 17:45:25 +0200 +Subject: [PATCH 2/2] obex: Allow using obexd w/o systemd user session + +Not all sessions run systemd --user (actually, the majority +doesn't), so the dbus daemon must be able to spawn obexd +directly, and to do so it needs the full path of the daemon. +--- + Makefile.obexd | 4 ++-- + obexd/src/{org.bluez.obex.service => org.bluez.obex.service.in} | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + rename obexd/src/{org.bluez.obex.service => org.bluez.obex.service.in} (76%) + +diff --git a/Makefile.obexd b/Makefile.obexd +index 2e33cbc72..d5d858c85 100644 +--- a/Makefile.obexd ++++ b/Makefile.obexd +@@ -2,12 +2,12 @@ + if SYSTEMD + systemduserunitdir = @SYSTEMD_USERUNITDIR@ + systemduserunit_DATA = obexd/src/obex.service ++endif + + dbussessionbusdir = @DBUS_SESSIONBUSDIR@ + dbussessionbus_DATA = obexd/src/org.bluez.obex.service +-endif + +-EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service ++EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service.in + + obex_plugindir = $(libdir)/obex/plugins + +diff --git a/obexd/src/org.bluez.obex.service b/obexd/src/org.bluez.obex.service.in +similarity index 76% +rename from obexd/src/org.bluez.obex.service +rename to obexd/src/org.bluez.obex.service.in +index a53808884..9c815f246 100644 +--- a/obexd/src/org.bluez.obex.service ++++ b/obexd/src/org.bluez.obex.service.in +@@ -1,4 +1,4 @@ + [D-BUS Service] + Name=org.bluez.obex +-Exec=/bin/false ++Exec=@libexecdir@/obexd + SystemdService=dbus-org.bluez.obex.service +-- +2.14.1 + diff --git a/0002-obexd-Fix-compilation-error-on-F27.patch b/0002-obexd-Fix-compilation-error-on-F27.patch new file mode 100644 index 0000000..be3d415 --- /dev/null +++ b/0002-obexd-Fix-compilation-error-on-F27.patch @@ -0,0 +1,32 @@ +From 9b760ecfa7d0f96bbac3ff606fbd560d58b2d1a6 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Thu, 24 Aug 2017 16:58:46 +0200 +Subject: [PATCH 2/4] obexd: Fix compilation error on F27 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In file included from obexd/plugins/mas.c:41:0: +./obexd/src/obex.h:37:1: error: unknown type name ‘ssize_t’; did you mean ‘size_t’? + ssize_t obex_get_size(struct obex_session *os); + ^~~~~~~ +--- + obexd/src/obex.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/obexd/src/obex.h b/obexd/src/obex.h +index fc1674755..67593f11b 100644 +--- a/obexd/src/obex.h ++++ b/obexd/src/obex.h +@@ -22,6 +22,8 @@ + * + */ + ++#include ++ + #define OBJECT_SIZE_UNKNOWN -1 + #define OBJECT_SIZE_DELETE -2 + +-- +2.14.1 + diff --git a/0003-sixaxis-Ask-user-whether-cable-configuration-should-.patch b/0003-sixaxis-Ask-user-whether-cable-configuration-should-.patch new file mode 100644 index 0000000..003d4d8 --- /dev/null +++ b/0003-sixaxis-Ask-user-whether-cable-configuration-should-.patch @@ -0,0 +1,166 @@ +From 8bb84509033bd0f3251d795627f1d9966edc1a18 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 7 Jul 2015 15:42:25 +0200 +Subject: [PATCH 3/9] sixaxis: Ask user whether cable configuration should be + allowed + +Previously, users doing cable configuration of Sixaxis PS3 controllers +would only get asked whether a device was allowed to connect to the +computer when switching it to Bluetooth mode: unplugging it, and +pressing the PS button. + +Instead, we should ask the user straight away, through the agent, +whether the pad should be allowed to connect. + +This makes it easier to setup those devices, while keeping security. +--- + plugins/sixaxis.c | 83 +++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 63 insertions(+), 20 deletions(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index 7d3a8f3ac..c8305d52f 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -44,6 +44,7 @@ + + #include "src/adapter.h" + #include "src/device.h" ++#include "src/agent.h" + #include "src/plugin.h" + #include "src/log.h" + #include "src/shared/util.h" +@@ -71,6 +72,13 @@ static const struct { + }, + }; + ++struct authentication_closure { ++ struct btd_adapter *adapter; ++ struct btd_device *device; ++ int fd; ++ char device_addr[18]; ++}; ++ + static struct udev *ctx = NULL; + static struct udev_monitor *monitor = NULL; + static guint watch_id = 0; +@@ -135,19 +143,51 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr) + return ret; + } + ++static void agent_auth_cb(DBusError *derr, ++ void *user_data) ++{ ++ struct authentication_closure *closure = user_data; ++ char master_addr[18], adapter_addr[18]; ++ bdaddr_t master_bdaddr; ++ const bdaddr_t *adapter_bdaddr; ++ ++ if (derr != NULL) { ++ DBG("Agent replied negatively, removing temporary device"); ++ goto error; ++ } ++ ++ btd_device_set_temporary(closure->device, false); ++ ++ if (get_master_bdaddr(closure->fd, &master_bdaddr) < 0) ++ goto error; ++ ++ adapter_bdaddr = btd_adapter_get_address(closure->adapter); ++ if (bacmp(adapter_bdaddr, &master_bdaddr)) { ++ if (set_master_bdaddr(closure->fd, adapter_bdaddr) < 0) ++ goto error; ++ } ++ ++ ba2str(&master_bdaddr, master_addr); ++ ba2str(adapter_bdaddr, adapter_addr); ++ DBG("remote %s old_master %s new_master %s", ++ closure->device_addr, master_addr, adapter_addr); ++ ++error: ++ close(closure->fd); ++ g_free(closure); ++} ++ + static bool setup_device(int fd, int index, struct btd_adapter *adapter) + { +- char device_addr[18], master_addr[18], adapter_addr[18]; +- bdaddr_t device_bdaddr, master_bdaddr; ++ char device_addr[18]; ++ bdaddr_t device_bdaddr; + const bdaddr_t *adapter_bdaddr; + struct btd_device *device; ++ struct authentication_closure *closure; + + if (get_device_bdaddr(fd, &device_bdaddr) < 0) + return false; + +- if (get_master_bdaddr(fd, &master_bdaddr) < 0) +- return false; +- + /* This can happen if controller was plugged while already connected + * eg. to charge up battery. */ + device = btd_adapter_find_device(adapter, &device_bdaddr, +@@ -155,25 +195,14 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter) + if (device && btd_device_is_connected(device)) + return false; + +- adapter_bdaddr = btd_adapter_get_address(adapter); +- +- if (bacmp(adapter_bdaddr, &master_bdaddr)) { +- if (set_master_bdaddr(fd, adapter_bdaddr) < 0) +- return false; +- } +- + ba2str(&device_bdaddr, device_addr); +- ba2str(&master_bdaddr, master_addr); +- ba2str(adapter_bdaddr, adapter_addr); +- DBG("remote %s old_master %s new_master %s", +- device_addr, master_addr, adapter_addr); + + device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR); + + if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID, + (GCompareFunc)strcasecmp)) { + DBG("device %s already known, skipping", device_addr); +- return true; ++ return false; + } + + info("sixaxis: setting up new device"); +@@ -181,7 +210,20 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter) + 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_set_temporary(device, false); ++ btd_device_set_temporary(device, true); ++ ++ closure = g_try_new0(struct authentication_closure, 1); ++ if (!closure) { ++ btd_adapter_remove_device(adapter, device); ++ return false; ++ } ++ closure->adapter = adapter; ++ closure->device = device; ++ closure->fd = fd; ++ memcpy(&closure->device_addr, device_addr, sizeof(device_addr)); ++ adapter_bdaddr = btd_adapter_get_address(adapter); ++ btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr, ++ HID_UUID, agent_auth_cb, closure); + + return true; + } +@@ -236,8 +278,9 @@ static void device_added(struct udev_device *udevice) + if (fd < 0) + return; + +- setup_device(fd, index, adapter); +- close(fd); ++ /* Only close the fd if an authentication is not pending */ ++ if (!setup_device(fd, index, adapter)) ++ close(fd); + } + + static gboolean monitor_watch(GIOChannel *source, GIOCondition condition, +-- +2.14.1 + diff --git a/0003-tools-csr_usb-Fix-compilation-failure.patch b/0003-tools-csr_usb-Fix-compilation-failure.patch new file mode 100644 index 0000000..1113fe7 --- /dev/null +++ b/0003-tools-csr_usb-Fix-compilation-failure.patch @@ -0,0 +1,41 @@ +From 07a12a6685ea57be18f39e349dbc42e4af3744ed Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 5 Sep 2017 10:32:15 +0200 +Subject: [PATCH 3/4] tools/csr_usb: Fix compilation failure + +GCC's "format-nonliteral" security check is enabled as an error in +recent versions of Fedora. Given the reduced scope of use, mark the +error as ignorable through pragma. + +tools/csr_usb.c: In function 'read_value': +tools/csr_usb.c:82:2: error: format not a string literal, argument types not checked [-Werror=format-nonliteral] + n = fscanf(file, format, &value); + ^ +--- + tools/csr_usb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/csr_usb.c b/tools/csr_usb.c +index a1d7324f7..33e9968a2 100644 +--- a/tools/csr_usb.c ++++ b/tools/csr_usb.c +@@ -67,6 +67,8 @@ struct usbfs_bulktransfer { + #define USBFS_IOCTL_CLAIMINTF _IOR('U', 15, unsigned int) + #define USBFS_IOCTL_RELEASEINTF _IOR('U', 16, unsigned int) + ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wformat-nonliteral" + static int read_value(const char *name, const char *attr, const char *format) + { + char path[PATH_MAX]; +@@ -88,6 +90,7 @@ static int read_value(const char *name, const char *attr, const char *format) + fclose(file); + return value; + } ++#pragma GCC diagnostic pop + + static char *check_device(const char *name) + { +-- +2.14.1 + diff --git a/0004-agent-Assert-possible-infinite-loop.patch b/0004-agent-Assert-possible-infinite-loop.patch deleted file mode 100644 index 2746e0c..0000000 --- a/0004-agent-Assert-possible-infinite-loop.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 67e5477687a2753d3f7b300bcfdc74464d8ad41f Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Mon, 9 Dec 2013 18:04:56 +0100 -Subject: [PATCH 4/5] agent: Assert possible infinite loop - ---- - src/agent.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/agent.c b/src/agent.c -index bcba969..b292881 100644 ---- a/src/agent.c -+++ b/src/agent.c -@@ -203,6 +203,8 @@ void agent_unref(struct agent *agent) - if (agent->ref > 0) - return; - -+ g_assert (agent->ref == 0); -+ - if (agent->request) { - DBusError err; - agent_pincode_cb pincode_cb; --- -1.8.4.2 - diff --git a/0004-obex-Work-around-compilation-failure.patch b/0004-obex-Work-around-compilation-failure.patch new file mode 100644 index 0000000..70b8033 --- /dev/null +++ b/0004-obex-Work-around-compilation-failure.patch @@ -0,0 +1,41 @@ +From d746de1bbcd6e9349dbd990ff9d33351f0bad319 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 5 Sep 2017 10:46:03 +0200 +Subject: [PATCH 4/4] obex: Work-around compilation failure + +obexd/plugins/bluetooth.c: In function 'register_profile': +obexd/plugins/bluetooth.c:310:7: error: format not a string literal, argument types not checked [-Werror=format-nonliteral] + profile->driver->port); + ^~~~~~~ +obexd/plugins/bluetooth.c:314:7: error: format not a string literal, argument types not checked [-Werror=format-nonliteral] + profile->driver->name); + ^~~~~~~ +--- + obexd/plugins/bluetooth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c +index 3ee54325f..3e31eaef6 100644 +--- a/obexd/plugins/bluetooth.c ++++ b/obexd/plugins/bluetooth.c +@@ -302,6 +302,9 @@ static int register_profile(struct bluetooth_profile *profile) + &opt); + dict_append_entry(&opt, "AutoConnect", DBUS_TYPE_BOOLEAN, + &auto_connect); ++ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wformat-nonliteral" + if (profile->driver->record) { + if (profile->driver->port != 0) + xml = g_markup_printf_escaped(profile->driver->record, +@@ -312,6 +315,7 @@ static int register_profile(struct bluetooth_profile *profile) + xml = g_markup_printf_escaped(profile->driver->record, + profile->driver->channel, + profile->driver->name); ++#pragma GCC diagnostic pop + dict_append_entry(&opt, "ServiceRecord", DBUS_TYPE_STRING, + &xml); + g_free(xml); +-- +2.14.1 + diff --git a/0004-plugins-sixaxis-Move-device-discovery-to-shared-head.patch b/0004-plugins-sixaxis-Move-device-discovery-to-shared-head.patch new file mode 100644 index 0000000..6210bba --- /dev/null +++ b/0004-plugins-sixaxis-Move-device-discovery-to-shared-head.patch @@ -0,0 +1,259 @@ +From d3cd88dc5f83e4b23170288eddecd665ad1742eb Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +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 ++ * Copyright (C) 2011 Antonio Ospite ++ * Copyright (C) 2013 Szymon Janc ++ * ++ * ++ * 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 + diff --git a/0005-profiles-input-Use-sixaxis-header-to-simplify-device.patch b/0005-profiles-input-Use-sixaxis-header-to-simplify-device.patch new file mode 100644 index 0000000..464f649 --- /dev/null +++ b/0005-profiles-input-Use-sixaxis-header-to-simplify-device.patch @@ -0,0 +1,56 @@ +From 493f46056fba02eb767fc881089de2b204b9166a Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 25 Aug 2017 19:04:16 +0200 +Subject: [PATCH 5/9] profiles/input: Use sixaxis header to simplify device + detection + +Use the shared header to recognise whether a device is a Sixaxis device +or not. +--- + profiles/input/server.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/profiles/input/server.c b/profiles/input/server.c +index eb3fcf843..121c334d3 100644 +--- a/profiles/input/server.c ++++ b/profiles/input/server.c +@@ -43,6 +43,7 @@ + #include "src/device.h" + #include "src/profile.h" + ++#include "sixaxis.h" + #include "device.h" + #include "server.h" + +@@ -123,6 +124,7 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst) + { + struct btd_device *device; + uint16_t vid, pid; ++ CablePairingType type; + + device = btd_adapter_find_device(adapter_find(src), dst, BDADDR_BREDR); + if (!device) +@@ -131,18 +133,14 @@ 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) ++ type = get_pairing_type(vid, pid, NULL, NULL, NULL); ++ if (type == CABLE_PAIRING_SIXAXIS) + return true; + + /* DualShock 4 */ + if (vid == 0x054c && pid == 0x05c4) + return true; + +- /* Navigation Controller */ +- if (vid == 0x054c && pid == 0x042f) +- return true; +- + return false; + } + +-- +2.14.1 + diff --git a/0006-profiles-input-Add-DS4-devices-to-the-shared-header.patch b/0006-profiles-input-Add-DS4-devices-to-the-shared-header.patch new file mode 100644 index 0000000..cbde5dc --- /dev/null +++ b/0006-profiles-input-Add-DS4-devices-to-the-shared-header.patch @@ -0,0 +1,67 @@ +From f19baae3e53137522f4da94118af695b4213f657 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 25 Aug 2017 19:07:18 +0200 +Subject: [PATCH 6/9] profiles/input: Add DS4 devices to the shared header + +And simplify the detection code in server.c some more. +--- + profiles/input/server.c | 7 ++----- + profiles/input/sixaxis.h | 17 +++++++++++++++++ + 2 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/profiles/input/server.c b/profiles/input/server.c +index 121c334d3..ef428fefe 100644 +--- a/profiles/input/server.c ++++ b/profiles/input/server.c +@@ -134,11 +134,8 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst) + pid = btd_device_get_product(device); + + type = get_pairing_type(vid, pid, NULL, NULL, NULL); +- if (type == CABLE_PAIRING_SIXAXIS) +- return true; +- +- /* DualShock 4 */ +- if (vid == 0x054c && pid == 0x05c4) ++ if (type == CABLE_PAIRING_SIXAXIS || ++ type == CABLE_PAIRING_DS4) + return true; + + return false; +diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h +index 0b3c4e397..17a7dc3f7 100644 +--- a/profiles/input/sixaxis.h ++++ b/profiles/input/sixaxis.h +@@ -29,6 +29,7 @@ + typedef enum { + CABLE_PAIRING_UNSUPPORTED = 0, + CABLE_PAIRING_SIXAXIS, ++ CABLE_PAIRING_DS4, + } CablePairingType; + + static inline CablePairingType get_pairing_type(uint16_t vid, +@@ -61,6 +62,22 @@ static inline CablePairingType get_pairing_type(uint16_t vid, + .version = 0x0000, + .type = CABLE_PAIRING_SIXAXIS, + }, ++ { ++ .name = "Wireless Controller", ++ .source = 0x0002, ++ .vid = 0x054c, ++ .pid = 0x05c4, ++ .version = 0x0001, ++ .type = CABLE_PAIRING_DS4, ++ }, ++ { ++ .name = "Wireless Controller", ++ .source = 0x0002, ++ .vid = 0x054c, ++ .pid = 0x09cc, ++ .version = 0x0001, ++ .type = CABLE_PAIRING_DS4, ++ }, + }; + guint i; + +-- +2.14.1 + diff --git a/0007-plugins-sixaxis-Rename-sixaxis-specific-functions.patch b/0007-plugins-sixaxis-Rename-sixaxis-specific-functions.patch new file mode 100644 index 0000000..08a2b7a --- /dev/null +++ b/0007-plugins-sixaxis-Rename-sixaxis-specific-functions.patch @@ -0,0 +1,129 @@ +From 55653a27c21dbab1e63bdec08a63771ea8b8cb1f Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 25 Aug 2017 19:29:04 +0200 +Subject: [PATCH 7/9] plugins/sixaxis: Rename sixaxis specific functions + +And provide wrappers to prepare for the addition of other device types. +--- + plugins/sixaxis.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index 3e8ac06ca..b62834d72 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -55,13 +55,14 @@ struct authentication_closure { + struct btd_device *device; + int fd; + char device_addr[18]; ++ CablePairingType type; + }; + + static struct udev *ctx = NULL; + static struct udev_monitor *monitor = NULL; + static guint watch_id = 0; + +-static int get_device_bdaddr(int fd, bdaddr_t *bdaddr) ++static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr) + { + uint8_t buf[18]; + int ret; +@@ -82,7 +83,14 @@ static int get_device_bdaddr(int fd, bdaddr_t *bdaddr) + return 0; + } + +-static int get_master_bdaddr(int fd, bdaddr_t *bdaddr) ++static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type) ++{ ++ if (type == CABLE_PAIRING_SIXAXIS) ++ return sixaxis_get_device_bdaddr(fd, bdaddr); ++ return -1; ++} ++ ++static int sixaxis_get_master_bdaddr(int fd, bdaddr_t *bdaddr) + { + uint8_t buf[8]; + int ret; +@@ -103,7 +111,14 @@ static int get_master_bdaddr(int fd, bdaddr_t *bdaddr) + return 0; + } + +-static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr) ++static int get_master_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type) ++{ ++ if (type == CABLE_PAIRING_SIXAXIS) ++ return sixaxis_get_master_bdaddr(fd, bdaddr); ++ return -1; ++} ++ ++static int sixaxis_set_master_bdaddr(int fd, const bdaddr_t *bdaddr) + { + uint8_t buf[8]; + int ret; +@@ -121,6 +136,14 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr) + return ret; + } + ++static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr, ++ CablePairingType type) ++{ ++ if (type == CABLE_PAIRING_SIXAXIS) ++ return sixaxis_set_master_bdaddr(fd, bdaddr); ++ return -1; ++} ++ + static void agent_auth_cb(DBusError *derr, + void *user_data) + { +@@ -136,12 +159,12 @@ static void agent_auth_cb(DBusError *derr, + + btd_device_set_temporary(closure->device, false); + +- if (get_master_bdaddr(closure->fd, &master_bdaddr) < 0) ++ if (get_master_bdaddr(closure->fd, &master_bdaddr, closure->type) < 0) + goto error; + + adapter_bdaddr = btd_adapter_get_address(closure->adapter); + if (bacmp(adapter_bdaddr, &master_bdaddr)) { +- if (set_master_bdaddr(closure->fd, adapter_bdaddr) < 0) ++ if (set_master_bdaddr(closure->fd, adapter_bdaddr, closure->type) < 0) + goto error; + } + +@@ -161,6 +184,7 @@ static bool setup_device(int fd, + uint16_t vid, + uint16_t pid, + uint16_t version, ++ CablePairingType type, + struct btd_adapter *adapter) + { + char device_addr[18]; +@@ -169,7 +193,7 @@ static bool setup_device(int fd, + struct btd_device *device; + struct authentication_closure *closure; + +- if (get_device_bdaddr(fd, &device_bdaddr) < 0) ++ if (get_device_bdaddr(fd, &device_bdaddr, type) < 0) + return false; + + /* This can happen if controller was plugged while already connected +@@ -203,6 +227,7 @@ static bool setup_device(int fd, + closure->adapter = adapter; + closure->device = device; + closure->fd = fd; ++ closure->type = type; + memcpy(&closure->device_addr, device_addr, sizeof(device_addr)); + adapter_bdaddr = btd_adapter_get_address(adapter); + btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr, +@@ -269,7 +294,7 @@ static void device_added(struct udev_device *udevice) + } + + /* Only close the fd if an authentication is not pending */ +- if (!setup_device(fd, name, source, vid, pid, version, adapter)) ++ if (!setup_device(fd, name, source, vid, pid, version, type, adapter)) + close(fd); + + g_free(name); +-- +2.14.1 + diff --git a/0008-plugins-sixaxis-Add-support-for-DualShock-4-PS4-cabl.patch b/0008-plugins-sixaxis-Add-support-for-DualShock-4-PS4-cabl.patch new file mode 100644 index 0000000..d705188 --- /dev/null +++ b/0008-plugins-sixaxis-Add-support-for-DualShock-4-PS4-cabl.patch @@ -0,0 +1,140 @@ +From 84191be1d4903a92fd0e8f79b15335f0c9abf925 Mon Sep 17 00:00:00 2001 +From: Juha Kuikka +Date: Fri, 25 Aug 2017 19:35:19 +0200 +Subject: [PATCH 8/9] plugins/sixaxis: Add support for DualShock 4/PS4 cable + pairing + +This patch adds support for "pairing" a Dualshock4 controller over USB +into the sixaxis plugin, similarly to what the Sixaxis/PS3 controller +supported. + +Actual bonding happens on first connection, but the device will be +marked as trusted when the agent replies. + +This patch is based on DS4 supprt for sixpair tool by t0xicCode: +https://github.com/t0xicCode/sixpair/commit/975c38cb6cd61a2f0be350714f0f64cef5f0432c +--- + plugins/sixaxis.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 72 insertions(+), 1 deletion(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index b62834d72..eb15acb92 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -83,10 +83,34 @@ static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr) + return 0; + } + ++static int ds4_get_device_bdaddr(int fd, bdaddr_t *bdaddr) ++{ ++ uint8_t buf[7]; ++ int ret; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ buf[0] = 0x81; ++ ++ ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf); ++ if (ret < 0) { ++ error("ds4: failed to read device address (%s)", ++ strerror(errno)); ++ return ret; ++ } ++ ++ /* address is little-endian on DS4 */ ++ bacpy(bdaddr, (bdaddr_t*) (buf + 1)); ++ ++ return 0; ++} ++ + static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type) + { + if (type == CABLE_PAIRING_SIXAXIS) + return sixaxis_get_device_bdaddr(fd, bdaddr); ++ else if (type == CABLE_PAIRING_DS4) ++ return ds4_get_device_bdaddr(fd, bdaddr); + return -1; + } + +@@ -111,10 +135,34 @@ static int sixaxis_get_master_bdaddr(int fd, bdaddr_t *bdaddr) + return 0; + } + ++static int ds4_get_master_bdaddr(int fd, bdaddr_t *bdaddr) ++{ ++ uint8_t buf[16]; ++ int ret; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ buf[0] = 0x12; ++ ++ ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf); ++ if (ret < 0) { ++ error("ds4: failed to read master address (%s)", ++ strerror(errno)); ++ return ret; ++ } ++ ++ /* address is little-endian on DS4 */ ++ bacpy(bdaddr, (bdaddr_t*) (buf + 10)); ++ ++ return 0; ++} ++ + static int get_master_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type) + { + if (type == CABLE_PAIRING_SIXAXIS) + return sixaxis_get_master_bdaddr(fd, bdaddr); ++ else if (type == CABLE_PAIRING_DS4) ++ return ds4_get_master_bdaddr(fd, bdaddr); + return -1; + } + +@@ -136,11 +184,33 @@ static int sixaxis_set_master_bdaddr(int fd, const bdaddr_t *bdaddr) + return ret; + } + ++static int ds4_set_master_bdaddr(int fd, const bdaddr_t *bdaddr) ++{ ++ uint8_t buf[23]; ++ int ret; ++ ++ buf[0] = 0x13; ++ bacpy((bdaddr_t*) (buf + 1), bdaddr); ++ /* TODO: we could put the key here but ++ there is no way to force a re-loading ++ of link keys to the kernel from here. */ ++ memset(buf + 7, 0, 16); ++ ++ ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf); ++ if (ret < 0) ++ error("ds4: failed to write master address (%s)", ++ strerror(errno)); ++ ++ return ret; ++} ++ + static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr, + CablePairingType type) + { + if (type == CABLE_PAIRING_SIXAXIS) + return sixaxis_set_master_bdaddr(fd, bdaddr); ++ else if (type == CABLE_PAIRING_DS4) ++ return ds4_set_master_bdaddr(fd, bdaddr); + return -1; + } + +@@ -279,7 +349,8 @@ static void device_added(struct udev_device *udevice) + &name, + &source, + &version); +- if (type != CABLE_PAIRING_SIXAXIS) ++ if (type != CABLE_PAIRING_SIXAXIS && ++ type != CABLE_PAIRING_DS4) + return; + if (bus != BUS_USB) + return; +-- +2.14.1 + diff --git a/0009-plugins-sixaxis-Cancel-cable-pairing-if-unplugged.patch b/0009-plugins-sixaxis-Cancel-cable-pairing-if-unplugged.patch new file mode 100644 index 0000000..6640ad2 --- /dev/null +++ b/0009-plugins-sixaxis-Cancel-cable-pairing-if-unplugged.patch @@ -0,0 +1,290 @@ +From 9f8fa823a2c8fec78e5a210f5c4a77114652d2ea Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 1 Sep 2017 17:23:38 +0200 +Subject: [PATCH 9/9] plugins/sixaxis: Cancel cable pairing if unplugged + +Cancel pending authorization requests when the device is unplugged +while a request is pending. +--- + plugins/sixaxis.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 123 insertions(+), 15 deletions(-) + +diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c +index eb15acb92..5cae52c68 100644 +--- a/plugins/sixaxis.c ++++ b/plugins/sixaxis.c +@@ -51,6 +51,8 @@ + #include "profiles/input/sixaxis.h" + + struct authentication_closure { ++ guint auth_id; ++ char *sysfs_path; + struct btd_adapter *adapter; + struct btd_device *device; + int fd; +@@ -58,9 +60,29 @@ struct authentication_closure { + CablePairingType type; + }; + ++struct authentication_destroy_closure { ++ struct authentication_closure *closure; ++ bool remove_device; ++}; ++ + static struct udev *ctx = NULL; + static struct udev_monitor *monitor = NULL; + static guint watch_id = 0; ++static GHashTable *pending_auths = NULL; /* key = sysfs_path (const str), value = auth_closure */ ++ ++/* Make sure to unset auth_id if already handled */ ++static void auth_closure_destroy(struct authentication_closure *closure, ++ bool remove_device) ++{ ++ if (closure->auth_id) ++ btd_cancel_authorization(closure->auth_id); ++ ++ if (remove_device) ++ btd_adapter_remove_device(closure->adapter, closure->device); ++ close(closure->fd); ++ g_free(closure->sysfs_path); ++ g_free(closure); ++} + + static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr) + { +@@ -214,41 +236,83 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr, + return -1; + } + ++static bool is_auth_pending(struct authentication_closure *closure) ++{ ++ GHashTableIter iter; ++ gpointer value; ++ ++ g_hash_table_iter_init(&iter, pending_auths); ++ while (g_hash_table_iter_next(&iter, NULL, &value)) { ++ struct authentication_closure *c = value; ++ if (c == closure) ++ return true; ++ } ++ return false; ++} ++ ++static gboolean auth_closure_destroy_idle(gpointer user_data) ++{ ++ struct authentication_destroy_closure *destroy = user_data; ++ ++ auth_closure_destroy(destroy->closure, destroy->remove_device); ++ g_free(destroy); ++ ++ return false; ++} ++ + static void agent_auth_cb(DBusError *derr, + void *user_data) + { + struct authentication_closure *closure = user_data; ++ struct authentication_destroy_closure *destroy; + char master_addr[18], adapter_addr[18]; + bdaddr_t master_bdaddr; + const bdaddr_t *adapter_bdaddr; ++ bool remove_device = true; ++ ++ if (!is_auth_pending(closure)) ++ return; ++ ++ /* Don't try to remove this auth, we're handling it already */ ++ closure->auth_id = 0; + + if (derr != NULL) { + DBG("Agent replied negatively, removing temporary device"); +- goto error; ++ goto out; + } + +- btd_device_set_temporary(closure->device, false); +- + if (get_master_bdaddr(closure->fd, &master_bdaddr, closure->type) < 0) +- goto error; ++ goto out; + + adapter_bdaddr = btd_adapter_get_address(closure->adapter); + if (bacmp(adapter_bdaddr, &master_bdaddr)) { + if (set_master_bdaddr(closure->fd, adapter_bdaddr, closure->type) < 0) +- goto error; ++ goto out; + } + ++ remove_device = false; ++ btd_device_set_temporary(closure->device, false); ++ + ba2str(&master_bdaddr, master_addr); + ba2str(adapter_bdaddr, adapter_addr); + DBG("remote %s old_master %s new_master %s", + closure->device_addr, master_addr, adapter_addr); + +-error: +- close(closure->fd); +- g_free(closure); ++out: ++ g_hash_table_steal(pending_auths, closure->sysfs_path); ++ ++ /* btd_adapter_remove_device() cannot be called in this ++ * callback or it would lead to a double-free in while ++ * trying to cancel the authentication that's being processed, ++ * so clean up in an idle */ ++ destroy = g_new0(struct authentication_destroy_closure, 1); ++ destroy->closure = closure; ++ destroy->remove_device = remove_device; ++ g_idle_add(auth_closure_destroy_idle, destroy); + } + + static bool setup_device(int fd, ++ const char *sysfs_path, + const char *name, + uint16_t source, + uint16_t vid, +@@ -296,12 +360,15 @@ static bool setup_device(int fd, + } + closure->adapter = adapter; + closure->device = device; ++ closure->sysfs_path = g_strdup(sysfs_path); + closure->fd = fd; + closure->type = type; + memcpy(&closure->device_addr, device_addr, sizeof(device_addr)); + adapter_bdaddr = btd_adapter_get_address(adapter); +- btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr, +- HID_UUID, agent_auth_cb, closure); ++ closure->auth_id = btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr, ++ HID_UUID, agent_auth_cb, closure); ++ ++ g_hash_table_insert(pending_auths, closure->sysfs_path, closure); + + return true; + } +@@ -310,12 +377,14 @@ static CablePairingType get_pairing_type_for_device(struct udev_device *udevice, + uint16_t *bus, + uint16_t *vid, + uint16_t *pid, ++ char **sysfs_path, + char **name, + uint16_t *source, + uint16_t *version) + { + struct udev_device *hid_parent; + const char *hid_id; ++ CablePairingType ret; + + hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice, + "hid", NULL); +@@ -327,14 +396,17 @@ static CablePairingType get_pairing_type_for_device(struct udev_device *udevice, + if (sscanf(hid_id, "%hx:%hx:%hx", bus, vid, pid) != 3) + return -1; + +- return get_pairing_type(*vid, *pid, name, source, version); ++ ret = get_pairing_type(*vid, *pid, name, source, version); ++ *sysfs_path = g_strdup(udev_device_get_syspath(udevice)); ++ ++ return ret; + } + + static void device_added(struct udev_device *udevice) + { + struct btd_adapter *adapter; + uint16_t bus, vid, pid, source, version; +- char *name = NULL; ++ char *name = NULL, *sysfs_path = NULL; + CablePairingType type; + int fd; + +@@ -346,6 +418,7 @@ static void device_added(struct udev_device *udevice) + &bus, + &vid, + &pid, ++ &sysfs_path, + &name, + &source, + &version); +@@ -355,20 +428,39 @@ static void device_added(struct udev_device *udevice) + if (bus != BUS_USB) + return; + +- info("sixaxis: compatible device connected: %s (%04X:%04X)", +- name, vid, pid); ++ info("sixaxis: compatible device connected: %s (%04X:%04X %s)", ++ name, vid, pid, sysfs_path); + + fd = open(udev_device_get_devnode(udevice), O_RDWR); + if (fd < 0) { + g_free(name); ++ g_free(sysfs_path); + return; + } + + /* Only close the fd if an authentication is not pending */ +- if (!setup_device(fd, name, source, vid, pid, version, type, adapter)) ++ if (!setup_device(fd, sysfs_path, name, source, vid, pid, version, type, adapter)) + close(fd); + + g_free(name); ++ g_free(sysfs_path); ++} ++ ++static void device_removed(struct udev_device *udevice) ++{ ++ struct authentication_closure *closure; ++ const char *sysfs_path; ++ ++ sysfs_path = udev_device_get_syspath(udevice); ++ if (!sysfs_path) ++ return; ++ ++ closure = g_hash_table_lookup(pending_auths, sysfs_path); ++ if (!closure) ++ return; ++ ++ g_hash_table_steal(pending_auths, sysfs_path); ++ auth_closure_destroy(closure, true); + } + + static gboolean monitor_watch(GIOChannel *source, GIOCondition condition, +@@ -382,6 +474,8 @@ static gboolean monitor_watch(GIOChannel *source, GIOCondition condition, + + if (!g_strcmp0(udev_device_get_action(udevice), "add")) + device_added(udevice); ++ else if (!g_strcmp0(udev_device_get_action(udevice), "remove")) ++ device_removed(udevice); + + udev_device_unref(udevice); + +@@ -415,13 +509,27 @@ static int sixaxis_init(void) + watch_id = g_io_add_watch(channel, G_IO_IN, monitor_watch, NULL); + g_io_channel_unref(channel); + ++ pending_auths = g_hash_table_new(g_str_hash, ++ g_str_equal); ++ + return 0; + } + + static void sixaxis_exit(void) + { ++ GHashTableIter iter; ++ gpointer value; ++ + DBG(""); + ++ g_hash_table_iter_init(&iter, pending_auths); ++ while (g_hash_table_iter_next(&iter, NULL, &value)) { ++ struct authentication_closure *closure = value; ++ auth_closure_destroy(closure, true); ++ } ++ g_hash_table_destroy(pending_auths); ++ pending_auths = NULL; ++ + g_source_remove(watch_id); + watch_id = 0; + +-- +2.14.1 + diff --git a/bluez.spec b/bluez.spec index 96e914d..01353c5 100644 --- a/bluez.spec +++ b/bluez.spec @@ -1,18 +1,39 @@ Name: bluez Summary: Bluetooth utilities Version: 5.46 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2+ URL: http://www.bluez.org/ Source0: http://www.kernel.org/pub/linux/bluetooth/bluez-%{version}.tar.xz Source1: bluez.gitignore -# Non-upstream -Patch2: 0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch -Patch3: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch -Patch4: 0002-autopair-Don-t-handle-the-iCade.patch -Patch5: 0004-agent-Assert-possible-infinite-loop.patch +# https://github.com/hadess/bluez/commits/build-fixes-5.46 +Patch0: 0001-build-Enable-BIND_NOW.patch +Patch1: 0002-obexd-Fix-compilation-error-on-F27.patch +Patch2: 0003-tools-csr_usb-Fix-compilation-failure.patch +Patch3: 0004-obex-Work-around-compilation-failure.patch + +# https://github.com/hadess/bluez/commits/obex-5.46 +Patch4: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch +# Should not be necessary anymore +# Patch5: 0002-obex-Allow-using-obexd-w-o-systemd-user-session.patch + +# https://github.com/hadess/bluez/commits/autopair-5.46 +Patch5: 0001-autopair-Don-t-handle-the-iCade.patch + +# 5.47 patch: +Patch100: 0001-plugins-sixaxis-Use-the-same-device-name-as-the-kern.patch +# https://github.com/hadess/bluez/commits/ds4-cable-pairing +Patch101: 0001-plugins-sixaxis-Remove-LEDs-handling.patch +Patch102: 0002-adapter-Add-btd_request_authorization_cable_configur.patch +Patch103: 0003-sixaxis-Ask-user-whether-cable-configuration-should-.patch +Patch104: 0004-plugins-sixaxis-Move-device-discovery-to-shared-head.patch +Patch105: 0005-profiles-input-Use-sixaxis-header-to-simplify-device.patch +Patch106: 0006-profiles-input-Add-DS4-devices-to-the-shared-header.patch +Patch107: 0007-plugins-sixaxis-Rename-sixaxis-specific-functions.patch +Patch108: 0008-plugins-sixaxis-Add-support-for-DualShock-4-PS4-cabl.patch +Patch109: 0009-plugins-sixaxis-Cancel-cable-pairing-if-unplugged.patch BuildRequires: git-core BuildRequires: dbus-devel >= 1.6 @@ -232,6 +253,13 @@ sed -i 's/#\[Policy\]$/\[Policy\]/; s/#AutoEnable=false/AutoEnable=true/' ${RPM_ %{_userunitdir}/obex.service %changelog +* Mon Sep 04 2017 Bastien Nocera - 5.46-4 ++ bluez-5.46-4 +- Patches cleanup +- Add DualShock4 cable pairing support +- BIND_NOW support for RELRO +- iCade autopairing support + * Wed Aug 02 2017 Fedora Release Engineering - 5.46-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild