diff --git a/.abf.yml b/.abf.yml index ddb4bee..b862b0b 100644 --- a/.abf.yml +++ b/.abf.yml @@ -1,2 +1,2 @@ sources: - "bluez-4.101.tar.xz": 5e6d94686b1a0492c4aed59ba16601f4903c15e8 + bluez-5.18.tar.xz: 5d5121b7c4afba5b4b55c1e1db2ef5d77a362a43 diff --git a/0001-Add-sixaxis-cable-pairing-plugin.patch b/0001-Add-sixaxis-cable-pairing-plugin.patch deleted file mode 100644 index b20c9c8..0000000 --- a/0001-Add-sixaxis-cable-pairing-plugin.patch +++ /dev/null @@ -1,554 +0,0 @@ -From 64f9449656dbbb718d53a54ed8e7904e289280ec Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Fri, 30 Dec 2011 12:34:29 +0100 -Subject: [PATCH] Add sixaxis cable-pairing plugin - -Implement the old "sixpair" using libudev and libusb-1.0. - -When a Sixaxis device is plugged in, events are filtered, and -the device is selected, poked around to set the default Bluetooth -address, and added to the database of the current default adapter. ---- - Makefile.am | 9 +- - acinclude.m4 | 16 +++ - configure.ac | 1 + - plugins/cable.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/adapter.c | 19 +++ - src/adapter.h | 3 + - 6 files changed, 428 insertions(+), 2 deletions(-) - create mode 100644 plugins/cable.c - -diff --git a/Makefile.am b/Makefile.am -index 53fcbe9..f831a72 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -238,6 +238,11 @@ builtin_sources += thermometer/main.c \ - endif - - -+if CABLE -+builtin_modules += cable -+builtin_sources += plugins/cable.c -+endif -+ - builtin_modules += hciops mgmtops - builtin_sources += plugins/hciops.c plugins/mgmtops.c - -@@ -306,7 +311,7 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \ - src/event.h src/event.c \ - src/oob.h src/oob.c src/eir.h src/eir.c - src_bluetoothd_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@ @DBUS_LIBS@ \ -- -ldl -lrt -+ @CABLE_LIBS@ -ldl -lrt - src_bluetoothd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic \ - -Wl,--version-script=$(srcdir)/src/bluetooth.ver - -@@ -428,7 +433,7 @@ EXTRA_DIST += doc/manager-api.txt \ - - AM_YFLAGS = -d - --AM_CFLAGS += @DBUS_CFLAGS@ @GLIB_CFLAGS@ -+AM_CFLAGS += @DBUS_CFLAGS@ @GLIB_CFLAGS@ @CABLE_CFLAGS@ - - INCLUDES = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \ - -I$(srcdir)/audio -I$(srcdir)/sbc -I$(srcdir)/gdbus \ -diff --git a/acinclude.m4 b/acinclude.m4 -index 6505ad3..3f59989 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -139,6 +139,12 @@ AC_DEFUN([AC_PATH_UDEV], [ - AC_SUBST(UDEV_LIBS) - ]) - -+AC_DEFUN([AC_PATH_CABLE], [ -+ PKG_CHECK_MODULES(CABLE, libudev libusb-1.0, cable_found=yes, cable_found=no) -+ AC_SUBST(CABLE_CFLAGS) -+ AC_SUBST(CABLE_LIBS) -+]) -+ - AC_DEFUN([AC_PATH_SNDFILE], [ - PKG_CHECK_MODULES(SNDFILE, sndfile, sndfile_found=yes, sndfile_found=no) - AC_SUBST(SNDFILE_CFLAGS) -@@ -176,6 +182,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ - sndfile_enable=${sndfile_found} - hal_enable=no - usb_enable=${usb_found} -+ cable_enable=${cable_found} - alsa_enable=${alsa_found} - gstreamer_enable=${gstreamer_found} - audio_enable=yes -@@ -265,6 +272,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ - usb_enable=${enableval} - ]) - -+ AC_ARG_ENABLE(cable, AC_HELP_STRING([--enable-cable], [enable DeviceKit support]), [ -+ cable_enable=${enableval} -+ ]) -+ - AC_ARG_ENABLE(tools, AC_HELP_STRING([--enable-tools], [install Bluetooth utilities]), [ - tools_enable=${enableval} - ]) -@@ -366,6 +377,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ - AC_DEFINE(HAVE_LIBUSB, 1, [Define to 1 if you have USB library.]) - fi - -+ if (test "${cable_enable}" = "yes" && test "${cable_found}" = "yes"); then -+ AC_DEFINE(HAVE_CABLE, 1, [Define to 1 if you have libcable.]) -+ fi -+ - AM_CONDITIONAL(SNDFILE, test "${sndfile_enable}" = "yes" && test "${sndfile_found}" = "yes") - AM_CONDITIONAL(USB, test "${usb_enable}" = "yes" && test "${usb_found}" = "yes") - AM_CONDITIONAL(SBC, test "${alsa_enable}" = "yes" || test "${gstreamer_enable}" = "yes" || -@@ -398,4 +413,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [ - AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes") - AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes") - AM_CONDITIONAL(GATTMODULES, test "${gatt_enable}" = "yes") -+ AM_CONDITIONAL(CABLE, test "${cable_enable}" = "yes" && test "${cable_found}" = "yes") - ]) -diff --git a/configure.ac b/configure.ac -index 48b181e..45a4b15 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -46,6 +46,7 @@ AC_PATH_GSTREAMER - AC_PATH_USB - AC_PATH_UDEV - AC_PATH_SNDFILE -+AC_PATH_CABLE - AC_PATH_OUI - AC_PATH_READLINE - AC_PATH_CHECK -diff --git a/plugins/cable.c b/plugins/cable.c -new file mode 100644 -index 0000000..fe758db ---- /dev/null -+++ b/plugins/cable.c -@@ -0,0 +1,382 @@ -+/* -+ * -+ * BlueZ - Bluetooth protocol stack for Linux -+ * -+ * Copyright (C) 2009 Bastien Nocera -+ * -+ * -+ * 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 -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1 -+#include -+#include -+#include -+#include -+#include -+ -+#include "plugin.h" -+#include "log.h" -+ -+#include "adapter.h" -+#include "manager.h" -+#include "device.h" -+ -+#include "storage.h" -+#include "sdp_lib.h" -+ -+/* Vendor and product ID for the Sixaxis PS3 controller */ -+#define VENDOR 0x054c -+#define PRODUCT 0x0268 -+#define SIXAXIS_PNP_RECORD "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800" -+#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb" -+ -+static struct btd_device *create_cable_association(DBusConnection *conn, -+ struct btd_adapter *adapter, -+ const char *name, -+ const char *address, -+ guint32 vendor_id, -+ guint32 product_id, -+ const char *pnp_record) -+{ -+ sdp_record_t *rec; -+ struct btd_device *device; -+ bdaddr_t src, dst; -+ char srcaddr[18]; -+ -+ device = adapter_find_device(adapter, address); -+ if (device == NULL) { -+ device = device_create(conn, adapter, address, BDADDR_BREDR); -+ if (device != NULL) -+ adapter_create_device_for_device(conn, adapter, device); -+ } -+ if (device != NULL) { -+ device_set_temporary(device, FALSE); -+ device_set_name(device, name); -+ } -+ -+ str2ba(address, &dst); -+ adapter_get_address(adapter, &src); -+ ba2str(&src, srcaddr); -+ -+ write_device_name(&dst, &src, (char *) name); -+ -+ /* Store the device's SDP record */ -+ rec = record_from_string(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); -+ /* Don't write a profile, it will be updated when the device connects */ -+ -+ write_trust(srcaddr, address, "[all]", TRUE); -+ -+ return device; -+} -+ -+static char *get_bdaddr(libusb_device_handle *devh, int itfnum) -+{ -+ unsigned char msg[17]; -+ char *address; -+ int res; -+ -+ res = libusb_control_transfer(devh, -+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, -+ 0x01, 0x03f2, itfnum, -+ (void*) msg, sizeof(msg), -+ 5000); -+ -+ if (res < 0) { -+ DBG("Getting the device Bluetooth address failed"); -+ return NULL; -+ } -+ -+ address = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X", -+ msg[4], msg[5], msg[6], msg[7], msg[8], msg[9]); -+ -+ DBG("Device Bluetooth address: %s\n", address); -+ -+ return address; -+} -+ -+static gboolean set_master_bdaddr(libusb_device_handle *devh, int itfnum, char *host) -+{ -+ unsigned char msg[8]; -+ int mac[6]; -+ int res; -+ -+ if (sscanf(host, "%X:%X:%X:%X:%X:%X", -+ &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) != 6) { -+ return FALSE; -+ } -+ -+ msg[0] = 0x01; -+ msg[1] = 0x00; -+ msg[2] = mac[0]; -+ msg[3] = mac[1]; -+ msg[4] = mac[2]; -+ msg[5] = mac[3]; -+ msg[6] = mac[4]; -+ msg[7] = mac[5]; -+ -+ res = libusb_control_transfer(devh, -+ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, -+ 0x09, 0x03f5, itfnum, -+ (void*) msg, sizeof(msg), -+ 5000); -+ -+ if (res < 0) { -+ DBG("Setting the master Bluetooth address failed"); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+static void handle_usb_device(struct btd_adapter *adapter, -+ libusb_device *dev, -+ struct libusb_config_descriptor *cfg, -+ int itfnum, -+ const struct libusb_interface_descriptor *alt) -+{ -+ DBusConnection *conn; -+ libusb_device_handle *devh; -+ char *device_bdaddr; -+ char adapter_bdaddr[18]; -+ struct btd_device *device; -+ bdaddr_t dst; -+ -+ device_bdaddr = NULL; -+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); -+ if (conn == NULL) { -+ DBG("Failed to get on the bus"); -+ return; -+ } -+ -+ if (libusb_open(dev, &devh) < 0) { -+ DBG("Can't open device"); -+ goto bail; -+ } -+ libusb_detach_kernel_driver(devh, itfnum); -+ -+ if (libusb_claim_interface(devh, itfnum) < 0) { -+ DBG("Can't claim interface %d", itfnum); -+ goto bail; -+ } -+ -+ device_bdaddr = get_bdaddr(devh, itfnum); -+ if (device_bdaddr == NULL) { -+ DBG("Failed to get the Bluetooth address from the device"); -+ goto bail; -+ } -+ -+ device = create_cable_association(conn, -+ adapter, -+ "PLAYSTATION(R)3 Controller", -+ device_bdaddr, -+ VENDOR, PRODUCT, SIXAXIS_PNP_RECORD); -+ btd_device_add_uuid(device, HID_UUID); -+ -+ adapter_get_address(adapter, &dst); -+ ba2str(&dst, adapter_bdaddr); -+ DBG("Adapter bdaddr %s", adapter_bdaddr); -+ -+ if (set_master_bdaddr(devh, itfnum, adapter_bdaddr) == FALSE) { -+ DBG("Failed to set the master Bluetooth address"); -+ goto bail; -+ } -+ -+bail: -+ dbus_connection_unref(conn); -+ g_free(device_bdaddr); -+ libusb_release_interface(devh, itfnum); -+ /* We ignore errors from the reattach, as there's nothing we -+ * can do about it */ -+ libusb_attach_kernel_driver(devh, itfnum); -+ if (devh != NULL) -+ libusb_close(devh); -+} -+ -+static void handle_device_plug(struct udev_device *udevice) -+{ -+ struct btd_adapter *adapter; -+ guint i; -+ -+ libusb_device **list, *usbdev; -+ ssize_t num_devices; -+ struct libusb_device_descriptor desc; -+ guint8 j; -+ -+ if (g_strcmp0(udev_device_get_property_value(udevice, "ID_SERIAL"), -+ "Sony_PLAYSTATION_R_3_Controller") != 0) -+ return; -+ /* Don't look at events with an associated driver */ -+ if (udev_device_get_property_value(udevice, "ID_USB_DRIVER") != NULL) -+ return; -+ -+ DBG("Found Sixaxis device"); -+ -+ /* Look for the default adapter */ -+ adapter = manager_get_default_adapter(); -+ if (adapter == NULL) -+ return; -+ -+ /* Look for the USB device */ -+ libusb_init(NULL); -+ -+ num_devices = libusb_get_device_list(NULL, &list); -+ if (num_devices < 0) { -+ DBG("libusb_get_device_list failed"); -+ return; -+ } -+ -+ usbdev = NULL; -+ for (i = 0; i < num_devices; i++) { -+ char *path; -+ -+ path = g_strdup_printf("%s/%03d/%03d", "/dev/bus/usb", -+ libusb_get_bus_number(list[i]), -+ libusb_get_device_address(list[i])); -+ if (g_strcmp0(path, udev_device_get_devnode(udevice)) == 0) { -+ g_free(path); -+ usbdev = libusb_ref_device(list[i]); -+ break; -+ } -+ g_free(path); -+ } -+ -+ libusb_free_device_list(list, TRUE); -+ if (usbdev == NULL) { -+ DBG("Found a Sixaxis, but couldn't find it via libusb"); -+ goto out; -+ } -+ -+ if (libusb_get_device_descriptor(usbdev, &desc) < 0) { -+ DBG("libusb_get_device_descriptor() failed"); -+ goto out; -+ } -+ -+ /* Look for the interface number that interests us */ -+ for (j = 0; j < desc.bNumConfigurations; j++) { -+ struct libusb_config_descriptor *config; -+ guint8 k; -+ -+ if (libusb_get_config_descriptor(usbdev, j, &config) < 0) { -+ DBG("Failed to get config descriptor %d", j); -+ continue; -+ } -+ -+ for (k = 0; k < config->bNumInterfaces; k++) { -+ const struct libusb_interface *itf = &config->interface[k]; -+ int l; -+ -+ for (l = 0; l < itf->num_altsetting ; l++) { -+ struct libusb_interface_descriptor alt; -+ -+ alt = itf->altsetting[l]; -+ if (alt.bInterfaceClass == 3) { -+ handle_usb_device(adapter, usbdev, config, l, &alt); -+ } -+ } -+ } -+ } -+ -+out: -+ if (usbdev != NULL) -+ libusb_unref_device(usbdev); -+ libusb_exit(NULL); -+} -+ -+static gboolean device_event_idle(struct udev_device *udevice) -+{ -+ handle_device_plug(udevice); -+ udev_device_unref(udevice); -+ return FALSE; -+} -+ -+static struct udev *ctx = NULL; -+static struct udev_monitor *monitor = NULL; -+static guint watch_id = 0; -+ -+static gboolean -+monitor_event(GIOChannel *source, -+ GIOCondition condition, -+ gpointer data) -+{ -+ struct udev_device *udevice; -+ -+ udevice = udev_monitor_receive_device(monitor); -+ if (udevice == NULL) -+ goto out; -+ if (g_strcmp0(udev_device_get_action(udevice), "add") != 0) -+ goto out; -+ -+ g_timeout_add_seconds(1, (GSourceFunc) device_event_idle, udevice); -+ -+out: -+ return TRUE; -+} -+ -+ -+static int cable_init(void) -+{ -+ GIOChannel *channel; -+ -+ DBG("Setup cable plugin"); -+ -+ ctx = udev_new(); -+ monitor = udev_monitor_new_from_netlink(ctx, "udev"); -+ if (monitor == NULL) { -+ error ("Could not get udev monitor"); -+ return -1; -+ } -+ -+ /* Listen for newly connected usb device */ -+ udev_monitor_filter_add_match_subsystem_devtype(monitor, -+ "usb", NULL); -+ udev_monitor_enable_receiving(monitor); -+ -+ channel = g_io_channel_unix_new(udev_monitor_get_fd(monitor)); -+ watch_id = g_io_add_watch(channel, G_IO_IN, monitor_event, NULL); -+ g_io_channel_unref(channel); -+ -+ return 0; -+} -+ -+static void cable_exit(void) -+{ -+ DBG("Cleanup cable plugin"); -+ -+ if (watch_id != 0) { -+ g_source_remove(watch_id); -+ watch_id = 0; -+ } -+ if (monitor != NULL) { -+ udev_monitor_unref(monitor); -+ monitor = NULL; -+ } -+ if (ctx != NULL) { -+ udev_unref(ctx); -+ ctx = NULL; -+ } -+} -+ -+BLUETOOTH_PLUGIN_DEFINE(cable, VERSION, -+ BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, cable_init, cable_exit) -diff --git a/src/adapter.c b/src/adapter.c -index 6e04faf..0488891 100644 ---- a/src/adapter.c -+++ b/src/adapter.c -@@ -952,6 +952,25 @@ static struct btd_device *adapter_create_device(DBusConnection *conn, - return device; - } - -+void adapter_create_device_for_device(DBusConnection *conn, -+ struct btd_adapter *adapter, -+ struct btd_device *device) -+{ -+ const char *path; -+ -+ device_set_temporary(device, TRUE); -+ -+ adapter->devices = g_slist_append(adapter->devices, device); -+ -+ path = device_get_path(device); -+ g_dbus_emit_signal(conn, adapter->path, -+ ADAPTER_INTERFACE, "DeviceCreated", -+ DBUS_TYPE_OBJECT_PATH, &path, -+ DBUS_TYPE_INVALID); -+ -+ adapter_update_devices(adapter); -+} -+ - void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter, - struct btd_device *device, - gboolean remove_storage) -diff --git a/src/adapter.h b/src/adapter.h -index b7ea62b..ac0aa2e 100644 ---- a/src/adapter.h -+++ b/src/adapter.h -@@ -114,6 +114,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, - uint8_t *data, uint8_t data_len); - void adapter_emit_device_found(struct btd_adapter *adapter, - struct remote_dev_info *dev); -+void adapter_create_device_for_device(DBusConnection *conn, -+ struct btd_adapter *adapter, -+ struct btd_device *device); - void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode); - int adapter_set_name(struct btd_adapter *adapter, const char *name); - void adapter_name_changed(struct btd_adapter *adapter, const char *name); --- -1.7.10.2 - 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 new file mode 100644 index 0000000..1ea3e6f --- /dev/null +++ b/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch @@ -0,0 +1,58 @@ +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-input-Add-helper-function-to-request-disconnect.patch b/0001-input-Add-helper-function-to-request-disconnect.patch deleted file mode 100644 index 481b72c..0000000 --- a/0001-input-Add-helper-function-to-request-disconnect.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c70bf65af6e301f18063491b22112300c0fb9b89 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Sun, 17 Jun 2012 01:25:46 +0200 -Subject: [PATCH 1/3] input: Add helper function to request disconnect - ---- - input/device.c | 7 +++++++ - input/device.h | 1 + - 2 files changed, 8 insertions(+) - -diff --git a/input/device.c b/input/device.c -index 0e3f4a9..8fdd4e0 100644 ---- a/input/device.c -+++ b/input/device.c -@@ -1306,3 +1306,10 @@ int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst) - - return 0; - } -+ -+void input_device_request_disconnect(struct fake_input *fake) -+{ -+ if (fake == NULL || fake->idev == NULL) -+ return; -+ device_request_disconnect(fake->idev->device, NULL); -+} -diff --git a/input/device.h b/input/device.h -index 509a353..ff52967 100644 ---- a/input/device.h -+++ b/input/device.h -@@ -49,3 +49,4 @@ int input_device_unregister(const char *path, const char *uuid); - int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, - GIOChannel *io); - int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst); -+void input_device_request_disconnect(struct fake_input *fake); --- -1.7.10 - diff --git a/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch b/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch new file mode 100644 index 0000000..004a389 --- /dev/null +++ b/0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch @@ -0,0 +1,38 @@ +From f7861d27fbcbc519f57d8496aa9486f487908821 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 + +Instead of trying to do it by hand. This also makes sure that +relative paths aren't used by the agent. +--- + obexd/src/manager.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/obexd/src/manager.c b/obexd/src/manager.c +index cec8a39..f18896e 100644 +--- a/obexd/src/manager.c ++++ b/obexd/src/manager.c +@@ -651,14 +651,14 @@ static void agent_reply(DBusPendingCall *call, void *user_data) + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + /* Splits folder and name */ +- const char *slash = strrchr(name, '/'); ++ gboolean is_relative = !g_path_is_absolute(name); + DBG("Agent replied with %s", name); +- if (!slash) { +- agent->new_name = g_strdup(name); ++ if (is_relative) { ++ agent->new_name = g_path_get_basename(name); + agent->new_folder = NULL; + } else { +- agent->new_name = g_strdup(slash + 1); +- agent->new_folder = g_strndup(name, slash - name); ++ agent->new_name = g_path_get_basename(name); ++ agent->new_folder = g_path_get_dirname(name); + } + } + +-- +1.8.4.2 + diff --git a/0001-work-around-Logitech-diNovo-Edge-keyboard-firmware-i.patch b/0001-work-around-Logitech-diNovo-Edge-keyboard-firmware-i.patch new file mode 100644 index 0000000..e583320 --- /dev/null +++ b/0001-work-around-Logitech-diNovo-Edge-keyboard-firmware-i.patch @@ -0,0 +1,29 @@ +From aa73bf5039dfd2cf0a52dd6fd22501d955cc1a00 Mon Sep 17 00:00:00 2001 +From: Tommy +Date: Thu, 10 Jan 2013 09:18:43 +0100 +Subject: [PATCH] work around Logitech diNovo Edge keyboard firmware issue + +https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/269851 +--- + tools/hid2hci.rules | 5 ++++- + 1 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/tools/hid2hci.rules b/tools/hid2hci.rules +index db6bb03..7db4572 100644 +--- a/tools/hid2hci.rules ++++ b/tools/hid2hci.rules +@@ -11,7 +11,10 @@ ATTR{bInterfaceClass}=="03", ATTR{bInterfaceSubClass}=="01", ATTR{bInterfaceProt + RUN+="hid2hci --method=dell --devpath=%p", ENV{HID2HCI_SWITCH}="1" + + # Logitech devices +-KERNEL=="hiddev*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[345abce]|c71[34bc]", \ ++KERNEL=="hiddev*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[345abce]|c71[3bc]", \ ++ RUN+="hid2hci --method=logitech-hid --devpath=%p" ++# Logitech, Inc. diNovo Edge Keyboard ++KERNEL=="hidraw*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c714", \ + RUN+="hid2hci --method=logitech-hid --devpath=%p" + + ENV{DEVTYPE}!="usb_device", GOTO="hid2hci_end" +-- +1.8.0.1 + diff --git a/0002-autopair-Don-t-handle-the-iCade.patch b/0002-autopair-Don-t-handle-the-iCade.patch new file mode 100644 index 0000000..68751ae --- /dev/null +++ b/0002-autopair-Don-t-handle-the-iCade.patch @@ -0,0 +1,47 @@ +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-fakehid-Disconnect-from-PS3-remote-after-10-mins.patch b/0002-fakehid-Disconnect-from-PS3-remote-after-10-mins.patch deleted file mode 100644 index 8941126..0000000 --- a/0002-fakehid-Disconnect-from-PS3-remote-after-10-mins.patch +++ /dev/null @@ -1,118 +0,0 @@ -From cca11542bcd4d1748c850806c1599ed1b76ea19a Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Sun, 17 Jun 2012 01:26:18 +0200 -Subject: [PATCH 2/3] fakehid: Disconnect from PS3 remote after 10 mins - -After 10 minutes, disconnect the PS3 BD Remote to avoid draining its -battery. This is consistent with its behaviour on the PS3. - -Original patch by Ruslan N. Marchenko ---- - input/device.h | 1 + - input/fakehid.c | 36 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - -diff --git a/input/device.h b/input/device.h -index ff52967..d8baa2c 100644 ---- a/input/device.h -+++ b/input/device.h -@@ -33,6 +33,7 @@ struct fake_input { - int uinput; /* uinput socket */ - int rfcomm; /* RFCOMM socket */ - uint8_t ch; /* RFCOMM channel number */ -+ guint timeout_id; /* Disconnect timeout ID */ - gboolean (*connect) (struct input_conn *iconn, GError **err); - int (*disconnect) (struct input_conn *iconn); - void *priv; -diff --git a/input/fakehid.c b/input/fakehid.c -index 3181538..a125356 100644 ---- a/input/fakehid.c -+++ b/input/fakehid.c -@@ -44,6 +44,9 @@ - #include "fakehid.h" - #include "uinput.h" - -+/* Timeout to get the PS3 remote disconnected, in seconds */ -+#define PS3_REMOTE_TIMEOUT 10 * 60 -+ - enum ps3remote_special_keys { - PS3R_BIT_PS = 0, - PS3R_BIT_ENTER = 3, -@@ -141,6 +144,20 @@ static unsigned int ps3remote_keymap[] = { - [0xff] = KEY_MAX, - }; - -+static gboolean ps3_remote_timeout_cb(gpointer user_data); -+ -+static void ps3remote_set_timeout(struct fake_input *fake, gboolean enable) -+{ -+ if (enable) { -+ fake->timeout_id = g_timeout_add_seconds(PS3_REMOTE_TIMEOUT, ps3_remote_timeout_cb, fake); -+ } else { -+ if (fake->timeout_id > 0) { -+ g_source_remove(fake->timeout_id); -+ fake->timeout_id = 0; -+ } -+ } -+} -+ - static int ps3remote_decode(char *buff, int size, unsigned int *value) - { - static unsigned int lastkey = 0; -@@ -203,6 +220,16 @@ error: - return -1; - } - -+static gboolean -+ps3_remote_timeout_cb(gpointer user_data) -+{ -+ struct fake_input *fake = (struct fake_input *) user_data; -+ input_device_request_disconnect(fake); -+ DBG("Disconnected PS3 BD Remote after timeout"); -+ fake->timeout_id = 0; -+ return FALSE; -+} -+ - static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond, - gpointer data) - { -@@ -221,6 +248,9 @@ static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond, - goto failed; - } - -+ /* Remove the old timeout */ -+ ps3remote_set_timeout(fake, FALSE); -+ - fd = g_io_channel_unix_get_fd(chan); - - memset(buff, 0, sizeof(buff)); -@@ -256,6 +286,8 @@ static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond, - goto failed; - } - -+ ps3remote_set_timeout(fake, TRUE); -+ - return TRUE; - - failed: -@@ -318,6 +350,8 @@ static int ps3remote_setup_uinput(struct fake_input *fake, - goto err; - } - -+ ps3remote_set_timeout(fake, TRUE); -+ - return 0; - - err: -@@ -378,6 +412,8 @@ struct fake_input *fake_hid_connadd(struct fake_input *fake, - for (l = fake_hid->devices; l != NULL; l = l->next) { - old = l->data; - if (old->idev == fake->idev) { -+ if (fake->timeout_id > 0) -+ g_source_remove(fake->timeout_id); - g_free(fake); - fake = old; - fake_hid->connect(fake, NULL); --- -1.7.10 - diff --git a/0002-systemd-unitdir-enable.patch b/0002-systemd-unitdir-enable.patch deleted file mode 100644 index f884dc0..0000000 --- a/0002-systemd-unitdir-enable.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 4319a0601457772591e520e407019b606780d035 Mon Sep 17 00:00:00 2001 -From: Alexander Khryukin -Date: Mon, 25 Jun 2012 13:16:23 -0400 -Subject: [PATCH 2/2] test - ---- - Makefile.am | 21 ++++++++++++++++++--- - configure.ac | 7 +++++++ - scripts/bluetooth.service.in | 14 ++++++++++++++ - scripts/org.bluez.service | 5 +++++ - 4 files changed, 44 insertions(+), 3 deletions(-) - create mode 100644 scripts/bluetooth.service.in - create mode 100644 scripts/org.bluez.service - -diff --git a/Makefile.am b/Makefile.am -index 1c214c6..024aa36 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -414,9 +414,24 @@ endif - rules_DATA = $(foreach file,$(udev_files), scripts/97-$(notdir $(file))) - endif - -+if HAVE_SYSTEMD -+systemdsystemunit_DATA = \ -+ scripts/bluetooth.service -+ -+scripts/bluetooth.service: scripts/bluetooth.service.in -+ @$(SED) -e "s|\@sbindir\@|$(sbindir)|" $< >$@ -+ -+dbussystemservicesdir = $(datadir)/dbus-1/system-services -+ -+dbussystemservices_DATA = \ -+ scripts/org.bluez.service -+endif -+ -+ - CLEANFILES += $(rules_DATA) - --EXTRA_DIST += scripts/bluetooth-hid2hci.rules scripts/bluetooth-serial.rules -+EXTRA_DIST += scripts/bluetooth-hid2hci.rules scripts/bluetooth-serial.rules \ -+ scripts/bluetooth.service.in scripts/org.bluez.service - - EXTRA_DIST += doc/manager-api.txt \ - doc/adapter-api.txt doc/device-api.txt \ -@@ -460,9 +475,9 @@ pkgconfigdir = $(libdir)/pkgconfig - - pkgconfig_DATA = bluez.pc - --DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles -+DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles --with-systemdsystemunitdir= - --DISTCLEANFILES = $(pkgconfig_DATA) -+DISTCLEANFILES = $(pkgconfig_DATA) scripts/bluetooth.service - - MAINTAINERCLEANFILES = Makefile.in \ - aclocal.m4 configure config.h.in config.sub config.guess \ -diff --git a/configure.ac b/configure.ac -index f2db920..6f6b4c0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -60,5 +60,12 @@ if (test -n "${path_systemdunit}"); then - AC_SUBST(SYSTEMD_UNITDIR) - fi - AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}") -+# systemd -+AC_ARG_WITH([systemdsystemunitdir], -+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), -+ [], -+ [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) -+AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) -+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"]) - - AC_OUTPUT(Makefile doc/version.xml src/bluetoothd.8 src/bluetooth.service bluez.pc) -diff --git a/scripts/bluetooth.service.in b/scripts/bluetooth.service.in -new file mode 100644 -index 0000000..5ec0e2a ---- /dev/null -+++ b/scripts/bluetooth.service.in -@@ -0,0 +1,14 @@ -+[Unit] -+Description=Bluetooth Manager -+After=syslog.target -+ -+[Service] -+Type=dbus -+BusName=org.bluez -+ExecStart=@sbindir@/bluetoothd -n -+StandardOutput=syslog -+ -+[Install] -+WantedBy=bluetooth.target -+Alias=dbus-org.bluez.service -+ -diff --git a/scripts/org.bluez.service b/scripts/org.bluez.service -new file mode 100644 -index 0000000..dd7ae8f ---- /dev/null -+++ b/scripts/org.bluez.service -@@ -0,0 +1,5 @@ -+[D-BUS Service] -+Name=org.bluez -+Exec=/bin/false -+User=root -+SystemdService=dbus-org.bluez.service --- -1.7.9.2 - diff --git a/0003-fakehid-Use-the-same-constant-as-declared.patch b/0003-fakehid-Use-the-same-constant-as-declared.patch deleted file mode 100644 index b6adf77..0000000 --- a/0003-fakehid-Use-the-same-constant-as-declared.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a354165e58f937ee12c16ab48ce334b664c8f163 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Sun, 17 Jun 2012 01:29:01 +0200 -Subject: [PATCH 3/3] fakehid: Use the same constant as declared - -ps3remote_keymap[] uses 0xff as the max value, so should we. ---- - input/fakehid.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/input/fakehid.c b/input/fakehid.c -index a125356..a758413 100644 ---- a/input/fakehid.c -+++ b/input/fakehid.c -@@ -335,7 +335,7 @@ static int ps3remote_setup_uinput(struct fake_input *fake, - } - - /* enabling keys */ -- for (i = 0; i < 256; i++) -+ for (i = 0; i < 0xff; i++) - if (ps3remote_keymap[i] != KEY_RESERVED) - if (ioctl(fake->uinput, UI_SET_KEYBIT, - ps3remote_keymap[i]) < 0) { --- -1.7.10 - diff --git a/0004-agent-Assert-possible-infinite-loop.patch b/0004-agent-Assert-possible-infinite-loop.patch new file mode 100644 index 0000000..2746e0c --- /dev/null +++ b/0004-agent-Assert-possible-infinite-loop.patch @@ -0,0 +1,25 @@ +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/0503-systemd-Fix-unit-to-correct-path-to-bluetoothd.patch b/0503-systemd-Fix-unit-to-correct-path-to-bluetoothd.patch deleted file mode 100644 index 1ff131d..0000000 --- a/0503-systemd-Fix-unit-to-correct-path-to-bluetoothd.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 811b28ca458c3e886a836c919fefa59eb0c4e53e Mon Sep 17 00:00:00 2001 -From: Colin Guthrie -Date: Mon, 5 Mar 2012 23:54:21 +0000 -Subject: [PATCH 503/503] systemd: Fix unit to correct path to bluetoothd. - ---- - src/bluetooth.service.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/bluetooth.service.in b/src/bluetooth.service.in -index 2a576a3..957aa35 100644 ---- a/src/bluetooth.service.in -+++ b/src/bluetooth.service.in -@@ -1,10 +1,10 @@ - [Unit] --Description=Bluetooth service -+Description=Bluetooth Manager - - [Service] - Type=dbus - BusName=org.bluez --ExecStart=@prefix@/sbin/bluetoothd -n -+ExecStart=@sbindir@/bluetoothd -n - - [Install] - WantedBy=bluetooth.target --- -1.7.11 - diff --git a/bluez-4.101-automake-1.13.patch b/bluez-4.101-automake-1.13.patch deleted file mode 100644 index 16bd1cc..0000000 --- a/bluez-4.101-automake-1.13.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- bluez-4.101/configure.ac.bero 2013-01-15 18:49:07.755043126 +0100 -+++ bluez-4.101/configure.ac 2013-01-15 18:49:15.743947380 +0100 -@@ -2,7 +2,7 @@ AC_PREREQ(2.60) - AC_INIT(bluez, 4.101) - - AM_INIT_AUTOMAKE([foreign subdir-objects color-tests]) --AM_CONFIG_HEADER(config.h) -+AC_CONFIG_HEADERS([config.h]) - - m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - diff --git a/bluez-4.101-fix-c++11-compatibility.patch b/bluez-4.101-fix-c++11-compatibility.patch deleted file mode 100644 index 627a88f..0000000 --- a/bluez-4.101-fix-c++11-compatibility.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- bluez-4.101/lib/bluetooth.h.c++11~ 2012-06-28 23:59:45.676069338 +0200 -+++ bluez-4.101/lib/bluetooth.h 2012-06-28 23:59:50.973003117 +0200 -@@ -140,16 +140,16 @@ enum { - #define bt_get_unaligned(ptr) \ - ({ \ - struct __attribute__((packed)) { \ -- typeof(*(ptr)) __v; \ -- } *__p = (typeof(__p)) (ptr); \ -+ __typeof__(*(ptr)) __v; \ -+ } *__p = (__typeof__(__p)) (ptr); \ - __p->__v; \ - }) - - #define bt_put_unaligned(val, ptr) \ - do { \ - struct __attribute__((packed)) { \ -- typeof(*(ptr)) __v; \ -- } *__p = (typeof(__p)) (ptr); \ -+ __typeof__(*(ptr)) __v; \ -+ } *__p = (__typeof__(__p)) (ptr); \ - __p->__v = (val); \ - } while(0) - diff --git a/bluez-socket-mobile-cf-connection-kit.patch b/bluez-socket-mobile-cf-connection-kit.patch deleted file mode 100644 index c3ef889..0000000 --- a/bluez-socket-mobile-cf-connection-kit.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/scripts/bluetooth-serial.rules b/scripts/bluetooth-serial.rules -index 072335f..f6284ff 100644 ---- a/scripts/bluetooth-serial.rules -+++ b/scripts/bluetooth-serial.rules -@@ -33,3 +33,7 @@ SUBSYSTEM=="tty", SUBSYSTEMS=="pcmcia", ATTRS{prod_id1}=="PCMCIA", ATTRS{prod_id - - # CC&C BT0100M - SUBSYSTEM=="tty", SUBSYSTEMS=="pcmcia", ATTRS{prod_id1}=="Bluetooth BT0100M", ENV{HCIOPTS}="bcsp 115200", RUN+="bluetooth_serial" -+ -+# SocketMobile CF Connection Kit -+SUBSYSTEM=="tty", SUBSYSTEMS=="pcmcia", ATTRS{prod_id1}=="Socket", ATTRS{prod_id2}=="CF+ Personal Network Card Rev 2.5", ENV{HCIOPTS}="socket", RUN+="bluetooth_serial" -+ diff --git a/bluez.spec b/bluez.spec index b2aff82..7457f80 100644 --- a/bluez.spec +++ b/bluez.spec @@ -2,12 +2,10 @@ %define libname %mklibname %{name} %{major} %define devname %mklibname -d %{name} -%bcond_without systemd - Name: bluez Summary: Official Linux Bluetooth protocol stack -Version: 4.101 -Release: 9 +Version: 5.18 +Release: 4 License: GPLv2+ Group: Communications URL: http://www.bluez.org/ @@ -18,99 +16,88 @@ Source8: hidd.conf Source9: rfcomm.conf Source10: bluez-uinput.modules -# http://thread.gmane.org/gmane.linux.bluez.kernel/8645 -Patch0: 0002-systemd-unitdir-enable.patch -Patch1: bluez-4.101-automake-1.13.patch -Patch4: bluez-socket-mobile-cf-connection-kit.patch -# http://thread.gmane.org/gmane.linux.bluez.kernel/2396 -Patch5: 0001-Add-sixaxis-cable-pairing-plugin.patch -# PS3 BD Remote patches -Patch6: 0001-input-Add-helper-function-to-request-disconnect.patch -Patch7: 0002-fakehid-Disconnect-from-PS3-remote-after-10-mins.patch -Patch8: 0003-fakehid-Use-the-same-constant-as-declared.patch -Patch9: bluez-4.101-fix-c++11-compatibility.patch +## https://bugzilla.redhat.com/show_bug.cgi?id=874015#c0 +Patch1: playstation-peripheral-pugin-v5.x.patch +## Ubuntu patches +Patch2: 0001-work-around-Logitech-diNovo-Edge-keyboard-firmware-i.patch +# Non-upstream +Patch3: 0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch -Patch0503: 0503-systemd-Fix-unit-to-correct-path-to-bluetoothd.patch +Patch4: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch +Patch5: 0002-autopair-Don-t-handle-the-iCade.patch +Patch7: 0004-agent-Assert-possible-infinite-loop.patch + +Requires(pre): rpm-helper BuildRequires: flex BuildRequires: bison -BuildRequires: systemd BuildRequires: readline-devel BuildRequires: expat-devel -BuildRequires: pkgconfig(alsa) +BuildRequires: cups-devel BuildRequires: pkgconfig(dbus-1) -BuildRequires: pkgconfig(gstreamer-plugins-base-0.10) -BuildRequires: pkgconfig(gstreamer-0.10) +BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libcap-ng) BuildRequires: pkgconfig(libusb) BuildRequires: pkgconfig(libusb-1.0) +BuildRequires: pkgconfig(libical) BuildRequires: pkgconfig(udev) >= 186 +BuildRequires: pkgconfig(libical) +BuildRequires: pkgconfig(systemd) Requires: bluez-pin Suggests: obex-data-server -Suggests: bluez-firmware +Obsoletes: bluez-alsa < 5.0 +Obsoletes: bluez-gstreamer < 5.0 %description These are the official Bluetooth communication libraries for Linux. %post -update-alternatives --install /bin/bluepin bluepin /usr/bin/bluepin 5 -#migrate old configuration -if [ "$1" = "2" -a -d %{_var}/lib/lib/bluetooth ]; then - mv -f %{_var}/lib/lib/bluetooth/* %{_var}/lib/bluetooth/ > /dev/null 2>&1 || exit 0 - rmdir %{_var}/lib/lib/bluetooth/ > /dev/null 2>&1 || exit 0 - rmdir %{_var}/lib/lib/ > /dev/null 2>&1 || exit 0 -fi - -if [ $1 -eq 1 ]; then - /bin/systemctl enable bluetooth.service >/dev/null 2>&1 || : -fi +%_post_service bluetooth %postun -if [ "$1" = "0" ]; then - update-alternatives --remove bluepin /usr/bin/bluepin -fi - -/bin/systemctl daemon-reload >/dev/null 2>&1 || : -if [ $1 -ge 1 ] ; then - /bin/systemctl try-restart bluetooth.service >/dev/null 2>&1 || : -fi - -%triggerun -- bluez < 4.94-4 -/bin/systemctl --no-reload enable bluetooth.service >/dev/null 2>&1 || : +%_preun_service bluetooth %files %{_bindir}/ciptool -%{_bindir}/dfutool -%{_bindir}/gatttool %{_bindir}/hcitool -%{_bindir}/hidd %{_bindir}/l2ping %{_bindir}/rfcomm %{_bindir}/sdptool -### compat -%{_bindir}/dund -%{_bindir}/pand -### -%{_sbindir}/bccmd -%{_sbindir}/hciattach -%{_sbindir}/hciconfig -%{_sbindir}/bluetoothd -/bin/hidd -/sbin/bluetoothd -%if %{with systemd} -%{_unitdir}/*.service -%endif -%{_mandir}/man?/* +%{_bindir}/bccmd +%{_bindir}/bluetoothctl +%{_bindir}/btmon +%{_bindir}/hciattach +%{_bindir}/hciconfig +%{_bindir}/hcidump +%{_bindir}/bluemoon +%{_libexecdir}/bluetooth/bluetoothd +%{_libexecdir}/bluetooth/obexd +%{_unitdir}/bluetooth.service +%{_unitdir}/dbus-org.bluez.service +%{_userunitdir}/obex.service +%{_mandir}/man1/ciptool.1.* +%{_mandir}/man1/hcitool.1.* +%{_mandir}/man1/rfcomm.1.* +%{_mandir}/man1/sdptool.1.* +%{_mandir}/man1/bccmd.1.* +%{_mandir}/man1/hciattach.1.* +%{_mandir}/man1/hciconfig.1.* +%{_mandir}/man1/hcidump.1.* +%{_mandir}/man1/l2ping.1.* +%{_mandir}/man1/rctest.1.* +%{_mandir}/man8/* %config(noreplace) %{_sysconfdir}/sysconfig/* %config(noreplace) %{_sysconfdir}/dbus-1/system.d/*.conf %config(noreplace) %{_sysconfdir}/bluetooth %{_datadir}/dbus-1/system-services/org.bluez.service -/lib/udev/bluetooth_serial -/lib/udev/hid2hci -%{_sysconfdir}/udev/rules.d/97-bluetooth-serial.rules -%{_sysconfdir}/udev/rules.d/97-bluetooth-hid2hci.rules +%{_datadir}/dbus-1/services/org.bluez.obex.service %{_localstatedir}/lib/bluetooth +%dir %{_libdir}/bluetooth +%dir %{_libdir}/bluetooth/plugins +%{_libdir}/bluetooth/plugins/sixaxis.so +%{_libdir}/bluetooth/plugins/playstation-peripheral.so + #-------------------------------------------------------------------- @@ -127,31 +114,6 @@ This package contains the CUPS backend for Bluetooth printers. #-------------------------------------------------------------------- -%package gstreamer -Summary: Gstreamer support for SBC audio format -Group: Sound - -%description gstreamer -This package contains gstreamer plugins for the Bluetooth SBC audio format - -%files gstreamer -%{_libdir}/gstreamer-*/*.so - -#-------------------------------------------------------------------- - -%package alsa -Summary: ALSA support for Bluetooth audio devices -Group: Sound - -%description alsa -This package contains ALSA support for Bluetooth audio devices - -%files alsa -%{_libdir}/alsa-lib/*.so -%{_datadir}/alsa/bluetooth.conf - -#-------------------------------------------------------------------- - %package -n %{libname} Summary: Official Linux Bluetooth protocol stack Group: System/Libraries @@ -160,7 +122,39 @@ Group: System/Libraries These are the official Bluetooth communication libraries for Linux. %files -n %{libname} -/%{_lib}/lib*.so.%{major}* +/%{_lib}/libbluetooth.so.%{major}* +#-------------------------------------------------------------------- + +%package hid2hci +Summary: Put HID proxying bluetooth HCI's into HCI mode +Group: Communications + +%description hid2hci +Most allinone PC's and bluetooth keyboard / mouse sets which include a +bluetooth dongle, ship with a so called HID proxying bluetooth HCI. +The HID proxying makes the keyboard / mouse show up as regular USB HID +devices (after connecting using the connect button on the device + keyboard), +which makes them work without requiring any manual configuration. + +The bluez-hid2hci package contains the hid2hci utility and udev rules to +automatically switch supported Bluetooth devices into regular HCI mode. + +Install this package if you want to use the bluetooth function of the HCI +with other bluetooth devices like for example a mobile phone. + +Note that after installing this package you will first need to pair your +bluetooth keyboard and mouse with the bluetooth adapter before you can use +them again. Since you cannot use your bluetooth keyboard and mouse until +they are paired, this will require the use of a regular (wired) USB keyboard +and mouse. + +%files hid2hci +/lib/udev/hid2hci +%{_mandir}/man1/hid2hci.1* +/lib/udev/rules.d/97-hid2hci.rules + +%post hid2hci +%{_bindir}/udevadm trigger --subsystem-match=usb #-------------------------------------------------------------------- @@ -176,27 +170,27 @@ BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A. %files test %{_bindir}/simple-agent +%{_bindir}/l2test +%{_bindir}/rctest %{_bindir}/test-* #-------------------------------------------------------------------- +%package -n %{devname} +Summary: Headers for developing programs that will use %{name} +Group: Development/C++ +Requires: %{libname} = %{version} +Provides: %{name}-devel = %{version}-%{release} -%package -n %{devname} -Summary: Headers for developing programs that will use %{name} -Group: Development/C++ -Requires: %{libname} = %{version} -Provides: %{name}-devel = %{version}-%{release} - -%description -n %{devname} +%description -n %{devname} This package contains the headers that programmers will need to develop applications which will use libraries from %{name}. -%files -n %{devname} +%files -n %{devname} %doc AUTHORS ChangeLog README %dir %{_includedir}/bluetooth %{_includedir}/bluetooth/*.h -/%{_lib}/*.so +%{_libdir}/*.so %{_libdir}/pkgconfig/bluez.pc - #-------------------------------------------------------------------- %prep @@ -208,82 +202,61 @@ autoreconf -fi %build %configure2_5x \ - --libdir=/%{_lib} \ -%if !%{with systemd} - --without-systemdsystemunitdir \ -%endif --enable-cups \ - --enable-dfutool \ - --enable-audio \ - --enable-health \ - --disable-hal \ - --enable-pnat \ - --enable-wiimote \ + --enable-sixaxis \ + --enable-udev \ --enable-tools \ - --enable-bccmd \ - --enable-gstreamer \ - --enable-hidd \ - --enable-pand \ - --enable-dund \ - --enable-hid2hci \ - --enable-pcmcia \ - --with-systemdsystemunitdir=/lib/systemd/system + --enable-library \ + --enable-usb \ + --enable-threads \ + --enable-monitor \ + --enable-obex \ + --enable-client \ + --enable-systemd \ + --with-systemdsystemunitdir=%{_unitdir} \ + --with-systemduserunitdir=%{_userunitdir} \ + --with-udevdir=/lib/udev \ + --enable-datafiles \ + --enable-experimental \ + --enable-playstation-peripheral %make %install %makeinstall_std rulesdir=%{_sysconfdir}/udev/rules.d udevdir=/lib/udev -mkdir -p %{buildroot}%{_libdir} -mv %{buildroot}/%{_lib}/gstreamer-0.10 %{buildroot}%{_libdir} - -cat << EOF > %{buildroot}%{_sysconfdir}/bluetooth/pin -1234 -EOF +mkdir -p %{buildroot}%{_sysconfdir}/bluetooth +echo "1234" > %{buildroot}%{_sysconfdir}/bluetooth/pin chmod 600 %{buildroot}%{_sysconfdir}/bluetooth/pin -rm -f %{buildroot}%{_sysconfdir}/default/bluetooth %{buildroot}%{_sysconfdir}/init.d/bluetooth install -m644 %{SOURCE6} -D %{buildroot}%{_sysconfdir}/sysconfig/pand install -m644 %{SOURCE7} -D %{buildroot}%{_sysconfdir}/sysconfig/dund install -m644 %{SOURCE8} -D %{buildroot}%{_sysconfdir}/sysconfig/hidd install -m644 %{SOURCE9} -D %{buildroot}%{_sysconfdir}/sysconfig/rfcomm -rm -rf %{buildroot}/%{_lib}/pkgconfig -install -m644 bluez.pc -D %{buildroot}%{_libdir}/pkgconfig/bluez.pc +mkdir -p %{buildroot}/%{_lib} +mv %{buildroot}%{_libdir}/libbluetooth.so.%{major}* %{buildroot}/%{_lib} +ln -srf %{buildroot}/%{_lib}/libbluetooth.so.%{major}.*.* %{buildroot}%{_libdir}/libbluetooth.so # Remove the cups backend from libdir, and install it in /usr/lib whatever the install -if test -d %{buildroot}/%{_lib}/cups ; then - install -D -m0755 %{buildroot}/%{_lib}/cups/backend/bluetooth %{buildroot}%{_prefix}/lib/cups/backend/bluetooth - rm -rf %{buildroot}/%{_lib}/cups -fi - +%if "%{_lib}" == "lib64" +install -d %{buildroot}%{_prefix}/lib +mv %{buildroot}%{_libdir}/cups %{buildroot}%{_prefix}/lib/cups +%endif + cp test/test-* %{buildroot}%{_bindir} cp test/simple-agent %{buildroot}%{_bindir}/simple-agent -rm -f %{buildroot}%{_bindir}/test-*.c -mkdir -p %{buildroot}/{bin,sbin} -mv %{buildroot}%{_bindir}/hidd %{buildroot}/bin -mv %{buildroot}%{_sbindir}/bluetoothd %{buildroot}/sbin -# sym link just to be safe -pushd %{buildroot} -ln -s /bin/hidd %{buildroot}%{_bindir}/hidd -ln -s /sbin/bluetoothd %{buildroot}%{_sbindir}/bluetoothd -popd +rm %{buildroot}%{_sysconfdir}/udev/rules.d/*.rules +install -p -m644 tools/hid2hci.rules -D %{buildroot}/lib/udev/rules.d/97-hid2hci.rules #install more config files -install -m0644 audio/audio.conf %{buildroot}%{_sysconfdir}/bluetooth/ -install -m0644 network/network.conf %{buildroot}%{_sysconfdir}/bluetooth/ -install -m0644 input/input.conf %{buildroot}%{_sysconfdir}/bluetooth/ -install -m0644 serial/serial.conf %{buildroot}%{_sysconfdir}/bluetooth/ - -mkdir -p %{buildroot}%{_libdir}/alsa-lib/ -mv %{buildroot}/%{_lib}/alsa-lib/*.so %{buildroot}%{_libdir}/alsa-lib/ +install -m0644 profiles/network/network.conf %{buildroot}%{_sysconfdir}/bluetooth/ +install -m0644 src/main.conf %{buildroot}%{_sysconfdir}/bluetooth/ +install -m0644 profiles/input/input.conf %{buildroot}%{_sysconfdir}/bluetooth/ +install -m0644 profiles/proximity/proximity.conf %{buildroot}%{_sysconfdir}/bluetooth/ install -d -m0755 %{buildroot}%{_localstatedir}/lib/bluetooth ln -s bluetooth.service %{buildroot}%{_unitdir}/dbus-org.bluez.service - -# (akdengi) enable auto for a2pd - -sed -e 's/#AutoConnect=true/AutoConnect=true/' -i %{buildroot}%{_sysconfdir}/bluetooth/audio.conf diff --git a/playstation-peripheral-pugin-v5.x.patch b/playstation-peripheral-pugin-v5.x.patch new file mode 100644 index 0000000..835d545 --- /dev/null +++ b/playstation-peripheral-pugin-v5.x.patch @@ -0,0 +1,835 @@ +--- bluez-5.18/Makefile.am.playstation~ 2014-03-25 21:53:41.000000000 +0100 ++++ bluez-5.18/Makefile.am 2014-05-06 22:13:18.967174167 +0200 +@@ -115,6 +115,15 @@ builtin_nodist = + + include Makefile.plugins + ++if PLAYSTATION_PERIPHERAL_PLUGIN ++plugin_LTLIBRARIES += plugins/playstation-peripheral.la ++plugins_playstation_peripheral_la_DEPENDENCIES = src/bluetoothd ++plugins_playstation_peripheral_la_SOURCES = plugins/playstation-peripheral.c plugins/playstation-peripheral-hid.c ++plugins_playstation_peripheral_la_LDFLAGS = -module -avoid-version -no-undefined @UDEV_LIBS@ ++plugins_playstation_peripheral_la_CFLAGS = -fvisibility=hidden @DBUS_CFLAGS@ @GLIB_CFLAGS@ @UDEV_CFLAGS@ ++plugins_playstation_peripheral_la_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/lib ++endif ++ + if MAINTAINER_MODE + plugin_LTLIBRARIES += plugins/external-dummy.la + plugins_external_dummy_la_SOURCES = plugins/external-dummy.c +--- bluez-5.18/configure.ac.playstation~ 2014-04-12 12:13:29.000000000 +0200 ++++ bluez-5.18/configure.ac 2014-05-06 22:09:30.225172158 +0200 +@@ -221,6 +221,16 @@ AC_ARG_ENABLE(sixaxis, AC_HELP_STRING([- + AM_CONDITIONAL(SIXAXIS, test "${enable_sixaxis}" = "yes" && + test "${enable_udev}" != "no") + ++AC_ARG_ENABLE(playstation_peripheral, AC_HELP_STRING([--enable-playstation-peripheral], ++ [enable playstation-peripheral plugin]), ++ [enable_playstation_peripheral=${enableval}]) ++ ++if (test "${enble_playstation_peripheral}" != "no" && test "${enable_udev}" != "no"); then ++ AC_DEFINE(HAVE_PLAYSTATION_PERIPHERAL_PLUGIN, 1, [Define to 1 if you have playstation-peripheral plugin.]) ++fi ++ ++AM_CONDITIONAL(PLAYSTATION_PERIPHERAL_PLUGIN, test "${enable_playstation_peripheral}" != "no" && test "${enable_udev}" != "no") ++ + if (test "${prefix}" = "NONE"); then + dnl no prefix and no localstatedir, so default to /var + if (test "$localstatedir" = '${prefix}/var'); then +--- bluez-5.18/plugins/playstation-peripheral-hid.c.playstation~ 2014-05-06 22:09:30.225172158 +0200 ++++ bluez-5.18/plugins/playstation-peripheral-hid.c 2014-05-06 22:09:30.225172158 +0200 +@@ -0,0 +1,263 @@ ++/* ++ * playstation peripheral plugin: lowlevel hid functions ++ * ++ * Copyright (C) 2011 Antonio Ospite ++ * ++ * ++ * 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 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "log.h" ++#include "playstation-peripheral-hid.h" ++ ++/* Fallback definitions to compile with older headers */ ++#ifndef HIDIOCGFEATURE ++#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) ++#endif ++ ++#ifndef HIDIOCSFEATURE ++#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) ++#endif ++ ++#define BDADDR_STR_SIZE 18 /* strlen("00:00:00:00:00:00") + 1 */ ++ ++#define LED_1 (0x01 << 1) ++#define LED_2 (0x01 << 2) ++#define LED_3 (0x01 << 3) ++#define LED_4 (0x01 << 4) ++ ++#define LED_STATUS_OFF 0 ++#define LED_STATUS_ON 1 ++ ++/* Usb cable pairing section */ ++static unsigned char *get_feature_report(int fd, uint8_t report_number, ++ unsigned int len) ++{ ++ unsigned char *buf; ++ int ret; ++ ++ buf = calloc(len, sizeof(*buf)); ++ if (buf == NULL) { ++ error("%s:%s() calloc failed", __FILE__, __func__); ++ return NULL; ++ } ++ ++ buf[0] = report_number; ++ ++ ret = ioctl(fd, HIDIOCGFEATURE(len), buf); ++ if (ret < 0) { ++ error("%s:%s() HIDIOCGFEATURE ret = %d", ++ __FILE__, __func__, ret); ++ free(buf); ++ return NULL; ++ } ++ ++ return buf; ++} ++ ++static int set_feature_report(int fd, uint8_t *report, int len) ++{ ++ int ret; ++ ++ ret = ioctl(fd, HIDIOCSFEATURE(len), report); ++ if (ret < 0) ++ error("%s:%s() HIDIOCSFEATURE failed, ret = %d", ++ __FILE__, __func__, ret); ++ ++ return ret; ++} ++ ++char *sixaxis_get_device_bdaddr(int fd) ++{ ++ unsigned char *buf; ++ char *address; ++ ++ buf = get_feature_report(fd, 0xf2, 18); ++ if (buf == NULL) { ++ error("%s:%s() cannot get feature report", __FILE__, __func__); ++ return NULL; ++ } ++ ++ address = calloc(BDADDR_STR_SIZE, sizeof(*address)); ++ if (address == NULL) { ++ error("%s:%s() calloc failed", __FILE__, __func__); ++ free(buf); ++ return NULL; ++ } ++ ++ snprintf(address, BDADDR_STR_SIZE, ++ "%02X:%02X:%02X:%02X:%02X:%02X", ++ buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]); ++ ++ free(buf); ++ return address; ++} ++ ++char *sixaxis_get_master_bdaddr(int fd) ++{ ++ unsigned char *buf; ++ char *address; ++ ++ buf = get_feature_report(fd, 0xf5, 8); ++ if (buf == NULL) { ++ error("%s:%s() cannot get feature report", __FILE__, __func__); ++ return NULL; ++ } ++ ++ address = calloc(BDADDR_STR_SIZE, sizeof(*address)); ++ if (address == NULL) { ++ error("%s:%s() calloc failed", __FILE__, __func__); ++ free(buf); ++ return NULL; ++ } ++ ++ snprintf(address, BDADDR_STR_SIZE, ++ "%02X:%02X:%02X:%02X:%02X:%02X", ++ buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); ++ ++ free(buf); ++ return address; ++} ++ ++int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr) ++{ ++ uint8_t *report; ++ uint8_t addr[6]; ++ int ret; ++ ++ ret = sscanf(adapter_bdaddr, ++ "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &addr[0], &addr[1], &addr[2], ++ &addr[3], &addr[4], &addr[5]); ++ if (ret != 6) { ++ error("%s:%s() Parsing the bt address failed", ++ __FILE__, __func__); ++ return -EINVAL; ++ } ++ ++ report = malloc(8); ++ if (report == NULL) { ++ error("%s:%s() malloc failed", __FILE__, __func__); ++ return -ENOMEM; ++ } ++ ++ report[0] = 0xf5; ++ report[1] = 0x01; ++ ++ report[2] = addr[0]; ++ report[3] = addr[1]; ++ report[4] = addr[2]; ++ report[5] = addr[3]; ++ report[6] = addr[4]; ++ report[7] = addr[5]; ++ ++ ret = set_feature_report(fd, report, 8); ++ if (ret < 0) { ++ error("%s:%s() cannot set feature report", ++ __FILE__, __func__); ++ goto out; ++ } ++ ++ DBG("New Master Bluetooth address: %s", adapter_bdaddr); ++ ++out: ++ free(report); ++ return ret; ++} ++ ++ ++/* Led setting section */ ++static int set_leds(int fd, unsigned char leds_status[4]) ++{ ++ int ret; ++ ++ /* ++ * the total time the led is active (0xff means forever) ++ * | duty_length: how long a cycle is in deciseconds: ++ * | | (0 means "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 is 100%) ++ * | | | | | ++ * 0xff, 0x27, 0x10, 0x00, 0x32, ++ */ ++ unsigned char leds_report[] = { ++ 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, /* rumble values TBD */ ++ 0x00, 0x00, 0x00, 0x00, 0x1e, /* 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 leds = 0; ++ if (leds_status[0]) ++ leds |= LED_1; ++ if (leds_status[1]) ++ leds |= LED_2; ++ if (leds_status[2]) ++ leds |= LED_3; ++ if (leds_status[3]) ++ leds |= LED_4; ++ ++ leds_report[10] = leds; ++ ++ ret = write(fd, leds_report, sizeof(leds_report)); ++ if (ret < (ssize_t) sizeof(leds_report)) ++ error("%s:%s() Unable to write to hidraw device", ++ __FILE__, __func__); ++ ++ return ret; ++} ++ ++int set_controller_number(int fd, unsigned int n) ++{ ++ unsigned char leds_status[4] = {0, 0, 0, 0}; ++ ++ switch (n) { ++ case 0: ++ break; ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ leds_status[n - 1] = LED_STATUS_ON; ++ break; ++ case 5: ++ case 6: ++ case 7: ++ leds_status[4 - 1] = LED_STATUS_ON; ++ leds_status[n - 4 - 1] = LED_STATUS_ON; ++ break; ++ default: ++ error("%s:%s() Only 7 controllers supported for now", ++ __FILE__, __func__); ++ return -1; ++ } ++ ++ return set_leds(fd, leds_status); ++} +--- bluez-5.18/plugins/playstation-peripheral-hid.h.playstation~ 2014-05-06 22:09:30.226172158 +0200 ++++ bluez-5.18/plugins/playstation-peripheral-hid.h 2014-05-06 22:09:30.226172158 +0200 +@@ -0,0 +1,10 @@ ++#ifndef __PLAYSTATION_PERIPHERAL_HID_H ++#define __PLAYSTATION_PERIPHERAL_HID_H ++ ++char *sixaxis_get_device_bdaddr(int fd); ++char *sixaxis_get_master_bdaddr(int fd); ++int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr); ++ ++int set_controller_number(int fd, unsigned int n); ++ ++#endif /* __PLAYSTATION_PERIPHERAL_HID_H */ +--- bluez-5.18/plugins/playstation-peripheral.c.playstation~ 2014-05-06 22:09:30.227172158 +0200 ++++ bluez-5.18/plugins/playstation-peripheral.c 2014-05-06 22:09:30.227172158 +0200 +@@ -0,0 +1,409 @@ ++/* ++ * playstation peripheral plugin: support for Playstation peripherals ++ * ++ * Copyright (C) 2009 Bastien Nocera ++ * Copyright (C) 2011 Antonio Ospite ++ * ++ * ++ * 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 ++ * ++ */ ++ ++/* ++ * In the following this terminology is used: ++ * ++ * - peripheral: a Playstation peripheral (Sixaxis, DS3, headset, etc.) ++ * - controller: an input peripheral ++ * - adapter: the bluetooth dongle on the host system. ++ * - adapter_bdaddr: the bdaddr of the bluetooth adapter. ++ * - device_bdaddr: the bdaddr of the Playstation peripheral. ++ * - master_bdaddr: the bdaddr of the adapter to be configured into the ++ * Playstation peripheral ++ * ++ * WHAT we need the plugin to do: ++ * ++ * - When a device is connected via USB: ++ * + Fetch the (default) adapter bdaddr (from BlueZ) and store it into ++ * the device ++ * + Fetch the device bdaddr (from the device via USB/HID) and make the ++ * device _trusted_ by the adapter (is "trusted" the correct term ++ * here? Or maybe this is more like a "static association"? Are the ++ * term "trusted" and "associated" in bluetooth context defined ++ * anywhere?) ++ * ++ * - When the device is connected via BT: ++ * + Nothing! It should work automatically. ++ * ++ * - Set LEDs when possible. ++ * ++ * WHY we need that: ++ * ++ * Playstation peripherals require/support USB cable pairing. ++ * ++ * It is required in the sense that devices will talk only to adapters ++ * they know. ++ * ++ * It is supported in the sense that this mechanism is optional on _some_ ++ * devices like the PS3 Keypad. ++ * ++ * On the PS3 these cable paired devices can be used via BT without ++ * further association steps once they have been connected ++ * _at_least_once_ via USB to a certain host (with a certain BT adapter ++ * that is), we would like to have the same behavior with BlueZ. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1 ++#include ++ ++#include "plugin.h" ++#include "log.h" ++#include "adapter.h" ++#include "device.h" ++#include "storage.h" ++#include "sdp_lib.h" ++ ++#include "playstation-peripheral-hid.h" ++ ++struct playstation_peripheral { ++ uint16_t vendor_id; ++ uint16_t product_id; ++ char *name; ++ char *sdp_record; ++ char *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 struct playstation_peripheral peripherals[] = { ++ { ++ .vendor_id = 0x054c, ++ .product_id = 0x0268, ++ .name = "PLAYSTATION(R)3 Controller", ++ .sdp_record = "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800", ++ .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, ++ }, ++}; ++ ++static struct udev *ctx; ++static struct udev_monitor *monitor; ++static guint watch_id; ++ ++static int create_peripheral_association(char *adapter_address, ++ char *device_address, ++ struct playstation_peripheral *peripheral) ++{ ++ return btd_create_stored_device(adapter_address, device_address, ++ peripheral->name, ++ 0x0002, /* VersionIDSource = USB Implementer's Forum */ ++ peripheral->vendor_id, ++ peripheral->product_id, ++ 0, /* version is hardcoded to 0 for now */ ++ peripheral->uuid, ++ peripheral->sdp_record, ++ 1); ++} ++ ++static int peripheral_pair(int fd, char *adapter_bdaddr, ++ struct playstation_peripheral *peripheral) ++{ ++ char *device_bdaddr; ++ char *master_bdaddr; ++ int ret = 0; ++ ++ master_bdaddr = peripheral->get_master_bdaddr(fd); ++ if (master_bdaddr == NULL) { ++ DBG("Failed to get the Old master Bluetooth address from the device"); ++ return -EPERM; ++ } ++ ++ /* Only set the master bdaddr when needed, this is how the PS3 does ++ * it, perhaps to avoid unnecessary writes to some eeprom. ++ */ ++ if (g_strcmp0(master_bdaddr, adapter_bdaddr) != 0) { ++ DBG("Old master Bluetooth address was: %s", master_bdaddr); ++ ret = peripheral->set_master_bdaddr(fd, adapter_bdaddr); ++ if (ret < 0) { ++ DBG("Failed to set the master Bluetooth address"); ++ free(master_bdaddr); ++ return ret; ++ } ++ } ++ ++ device_bdaddr = peripheral->get_device_bdaddr(fd); ++ if (device_bdaddr == NULL) { ++ DBG("Failed to get the Bluetooth address from the device"); ++ free(master_bdaddr); ++ return -EPERM; ++ } ++ ++ DBG("Device bdaddr %s", device_bdaddr); ++ ++ ret = create_peripheral_association(adapter_bdaddr, device_bdaddr, peripheral); ++ ++ free(device_bdaddr); ++ free(master_bdaddr); ++ return ret; ++} ++ ++static inline struct playstation_peripheral *find_playstation_peripheral(const char *hid_id) ++{ ++ unsigned int array_size = sizeof(peripherals)/sizeof(peripherals[0]); ++ unsigned int i; ++ int ret; ++ uint16_t protocol; ++ uint16_t vendor_id; ++ uint16_t product_id; ++ ++ ret = sscanf(hid_id, "%hx:%hx:%hx", &protocol, &vendor_id, &product_id); ++ if (ret != 3) { ++ error("%s:%s() Parsing HID_ID failed", ++ __FILE__, __func__); ++ return NULL; ++ } ++ ++ for (i = 0; i < array_size; i++) { ++ if (peripherals[i].vendor_id == vendor_id && ++ peripherals[i].product_id == product_id) ++ return &peripherals[i]; ++ } ++ ++ return NULL; ++} ++ ++static inline int is_usb_peripheral(const char *hid_id) ++{ ++ int ret; ++ uint16_t protocol; ++ uint16_t vendor_id; ++ uint16_t product_id; ++ ++ ret = sscanf(hid_id, "%hx:%hx:%hx", &protocol, &vendor_id, &product_id); ++ if (ret != 3) { ++ error("%s:%s() Parsing HID_ID failed", ++ __FILE__, __func__); ++ return 0; ++ } ++ ++ DBG("%hx:%hx:%hx", protocol, vendor_id, product_id); ++ return (protocol == 3); ++} ++ ++static void handle_device_plug(struct udev_device *udevice) ++{ ++ struct udev_device *hid_parent; ++ struct udev_enumerate *enumerate; ++ struct udev_list_entry *devices, *dev_list_entry; ++ const char *hid_id; ++ const char *hid_phys; ++ const char *hidraw_node; ++ unsigned char is_usb = FALSE; ++ int js_num = 0; ++ int fd; ++ struct playstation_peripheral *peripheral; ++ ++ hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice, ++ "hid", NULL); ++ if (!hid_parent) { ++ error("%s:%s() cannot get parent hid device", ++ __FILE__, __func__); ++ return; ++ } ++ ++ hid_id = udev_device_get_property_value(hid_parent, "HID_ID"); ++ DBG("HID_ID: %s", hid_id); ++ ++ peripheral = find_playstation_peripheral(hid_id); ++ if (!peripheral) { ++ error("No supported peripheral found"); ++ return; ++ } ++ ++ DBG("Found a Playstation peripheral: %s", peripheral->name); ++ ++ hidraw_node = udev_device_get_devnode(udevice); ++ ++ /* looking for joysticks */ ++ hid_phys = udev_device_get_property_value(hid_parent, "HID_PHYS"); ++ ++ 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) { ++ const char *devname; ++ struct udev_device *js_dev; ++ struct udev_device *input_parent; ++ const char *input_phys; ++ ++ 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) { ++ error("%s:%s() cannot get parent input device.", ++ __FILE__, __func__); ++ continue; ++ } ++ ++ /* check this is the joystick relative to ++ * the hidraw device above */ ++ input_phys = udev_device_get_sysattr_value(input_parent, ++ "phys"); ++ if (g_strcmp0(input_phys, hid_phys) == 0) { ++ js_num = atoi(udev_device_get_sysnum(js_dev)) + 1; ++ DBG("joypad device_num: %d", js_num); ++ DBG("hidraw_node: %s", hidraw_node); ++ } ++ ++ udev_device_unref(js_dev); ++ } ++ ++ udev_enumerate_unref(enumerate); ++ ++ fd = open(hidraw_node, O_RDWR); ++ if (fd < 0) { ++ error("%s:%s() hidraw open", __FILE__, __func__); ++ return; ++ } ++ ++ is_usb = is_usb_peripheral(hid_id); ++ if (is_usb) { ++ char *adapter_bdaddr; ++ ++ adapter_bdaddr = btd_adapter_get_default_address(); ++ if (adapter_bdaddr == NULL) { ++ error("No adapters, exiting"); ++ return; ++ } ++ ++ DBG("Adapter bdaddr %s", adapter_bdaddr); ++ ++ peripheral_pair(fd, adapter_bdaddr, peripheral); ++ free(adapter_bdaddr); ++ } ++ ++ if (js_num > 0) { ++ char c; ++ ++ /* wait for events before setting leds */ ++ if (read(fd, &c, 1) != 1) ++ error("%s:%s(): read error: %s", __FILE__, __func__, ++ strerror(errno)); ++ ++ set_controller_number(fd, js_num); ++ } ++ ++ close(fd); ++} ++ ++static gboolean device_event_idle(struct udev_device *udevice) ++{ ++ handle_device_plug(udevice); ++ udev_device_unref(udevice); ++ return FALSE; ++} ++ ++static gboolean monitor_event(GIOChannel *source, GIOCondition condition, ++ gpointer data) ++{ ++ struct udev_device *udevice; ++ ++ udevice = udev_monitor_receive_device(monitor); ++ if (udevice == NULL) ++ goto out; ++ if (g_strcmp0(udev_device_get_action(udevice), "add") != 0) { ++ udev_device_unref(udevice); ++ goto out; ++ } ++ ++ /* Give UDEV some time to load kernel modules */ ++ g_timeout_add_seconds(1, (GSourceFunc) device_event_idle, udevice); ++ ++out: ++ return TRUE; ++} ++ ++static int playstation_peripheral_init(void) ++{ ++ GIOChannel *channel; ++ ++ DBG("Setup Playstation peripheral plugin"); ++ ++ ctx = udev_new(); ++ monitor = udev_monitor_new_from_netlink(ctx, "udev"); ++ if (monitor == NULL) { ++ error("%s:%s() Could not get udev monitor", ++ __FILE__, __func__); ++ return -1; ++ } ++ ++ /* Listen for newly connected hidraw interfaces */ ++ udev_monitor_filter_add_match_subsystem_devtype(monitor, ++ "hidraw", NULL); ++ udev_monitor_enable_receiving(monitor); ++ ++ channel = g_io_channel_unix_new(udev_monitor_get_fd(monitor)); ++ watch_id = g_io_add_watch(channel, G_IO_IN, monitor_event, NULL); ++ g_io_channel_unref(channel); ++ ++ return 0; ++} ++ ++static void playstation_peripheral_exit(void) ++{ ++ DBG("Cleanup Playstation peripheral plugin"); ++ ++ if (watch_id != 0) { ++ g_source_remove(watch_id); ++ watch_id = 0; ++ } ++ if (monitor != NULL) { ++ udev_monitor_unref(monitor); ++ monitor = NULL; ++ } ++ if (ctx != NULL) { ++ udev_unref(ctx); ++ ctx = NULL; ++ } ++} ++ ++BLUETOOTH_PLUGIN_DEFINE(playstation_peripheral, VERSION, ++ BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, ++ playstation_peripheral_init, ++ playstation_peripheral_exit) +--- bluez-5.18/src/adapter.c.playstation~ 2014-04-12 12:13:29.000000000 +0200 ++++ bluez-5.18/src/adapter.c 2014-05-06 22:09:30.229172158 +0200 +@@ -240,6 +240,23 @@ struct btd_adapter *btd_adapter_get_defa + return NULL; + } + ++char *btd_adapter_get_default_address(void) ++{ ++ struct btd_adapter *adapter; ++ char *str; ++ ++ adapter = btd_adapter_get_default(); ++ if (adapter == NULL) ++ return NULL; ++ ++ str = bt_malloc(18); ++ if (str == NULL) ++ return NULL; ++ ++ ba2str(btd_adapter_get_address(adapter), str); ++ return str; ++} ++ + bool btd_adapter_is_default(struct btd_adapter *adapter) + { + if (!adapter) +@@ -6787,3 +6804,55 @@ void adapter_shutdown(void) + if (!adapter_remaining) + btd_exit(); + } ++ ++int btd_create_stored_device(char *adapter_address, ++ char *device_address, ++ char *name, ++ uint16_t vendor_id_source, ++ uint16_t vendor_id, ++ uint16_t product_id, ++ uint16_t version_id, ++ const char *uuid, ++ char *sdp_record, ++ bool trusted) ++{ ++ struct btd_adapter *adapter; ++ struct btd_device *device; ++ bdaddr_t dst; ++ int ret = 0; ++ ++ store_sdp_record(adapter_address, device_address, 0x10000, sdp_record); ++ ++ str2ba(device_address, &dst); ++ ++ adapter = btd_adapter_get_default(); ++ if (adapter == NULL) { ++ DBG("Failed to get the adapter"); ++ ret = -EPERM; ++ goto out; ++ } ++ ++ /* This will create the device if necessary */ ++ device = btd_adapter_get_device(adapter, &dst, BDADDR_BREDR); ++ if (device == NULL) { ++ DBG("Failed to get the device"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ if (name) ++ btd_device_device_set_name(device, name); ++ ++ btd_device_set_pnpid(device, vendor_id_source, ++ vendor_id, product_id, version_id); ++ ++ if (uuid) ++ btd_device_add_uuid(device, uuid); ++ ++ btd_device_set_temporary(device, FALSE); ++ ++ if (trusted) ++ btd_device_set_trusted(device, TRUE); ++out: ++ return ret; ++} +--- bluez-5.18/src/adapter.h.playstation~ 2014-03-25 21:53:42.000000000 +0100 ++++ bluez-5.18/src/adapter.h 2014-05-06 22:09:30.230172158 +0200 +@@ -39,6 +39,7 @@ struct btd_adapter; + struct btd_device; + + struct btd_adapter *btd_adapter_get_default(void); ++char *btd_adapter_get_default_address(void); + bool btd_adapter_is_default(struct btd_adapter *adapter); + uint16_t btd_adapter_get_index(struct btd_adapter *adapter); + +@@ -199,3 +200,14 @@ gboolean btd_adapter_check_oob_handler(s + void btd_adapter_for_each_device(struct btd_adapter *adapter, + void (*cb)(struct btd_device *device, void *data), + void *data); ++ ++int btd_create_stored_device(char *btd_adapter_address, ++ char *device_address, ++ char *name, ++ uint16_t vendor_id_source, ++ uint16_t vendor_id, ++ uint16_t product_id, ++ uint16_t version_id, ++ const char *uuid, ++ char *sdp_record, ++ bool trusted);