From d707091ec725bab3a942d2ae250dd136d905276d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Dec 11 2013 11:21:23 +0000 Subject: Update to 5.12 - Sixaxis PS3 joypad support is now upstream --- diff --git a/.gitignore b/.gitignore index 1aa56a7..150dde3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /bluez-5.9.tar.xz /bluez-5.10.tar.xz /bluez-5.11.tar.xz +/bluez-5.12.tar.xz diff --git a/0003-input-Fix-crash-when-SDP-record-isn-t-available.patch b/0003-input-Fix-crash-when-SDP-record-isn-t-available.patch deleted file mode 100644 index de22106..0000000 --- a/0003-input-Fix-crash-when-SDP-record-isn-t-available.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1da26fd3ce47728f423e290e3928257ead9baf76 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Sat, 7 Dec 2013 15:51:47 +0100 -Subject: [PATCH] input: Fix crash when SDP record isn't available - -On startup, if the SDP cache has been removed but the pairing -information is still present, we'd crash trying to access inside a -NULL record struct. ---- - profiles/input/device.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/profiles/input/device.c b/profiles/input/device.c -index 6523161..8a28b0d 100644 ---- a/profiles/input/device.c -+++ b/profiles/input/device.c -@@ -811,6 +811,9 @@ static struct input_device *input_device_new(struct btd_service *service) - struct input_device *idev; - char name[HCI_MAX_NAME_LENGTH + 1]; - -+ if (!rec) -+ return NULL; -+ - idev = g_new0(struct input_device, 1); - bacpy(&idev->src, adapter_get_address(adapter)); - bacpy(&idev->dst, device_get_address(device)); --- -1.8.4.2 - diff --git a/0005-core-Fix-crash-due-to-agent-callback-freeing-the-age.patch b/0005-core-Fix-crash-due-to-agent-callback-freeing-the-age.patch deleted file mode 100644 index 4c86cce..0000000 --- a/0005-core-Fix-crash-due-to-agent-callback-freeing-the-age.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 28419bdc2fd093bcbc68b629b9c7b8c295260c57 Mon Sep 17 00:00:00 2001 -From: Szymon Janc -Date: Mon, 9 Dec 2013 20:20:55 +0100 -Subject: [PATCH 5/5] core: Fix crash due to agent callback freeing the agent - -Similar fix was provided for simple_agent_reply in a2f5d438 but missed -pincode_reply case. - -Fix following: - -src/agent.c:agent_disconnect() Agent :1.48 disconnected -src/agent.c:set_default_agent() Default agent cleared -src/agent.c:agent_destroy() agent :1.48 -src/agent.c:agent_unref() 0x4701c68: ref=1 -Agent /org/bluez/agent replied with an error: - org.freedesktop.DBus.Error.NoReply, Message did not receive a reply - (timeout by message bus) -src/adapter.c:btd_adapter_pincode_reply() hci0 addr 6C:0E:0D:DB:D1:16 - pinlen 0 -src/agent.c:agent_unref() 0x4701c68: ref=0 -src/adapter.c:btd_adapter_pincode_reply() hci0 addr 6C:0E:0D:DB:D1:16 - pinlen 0 -src/agent.c:agent_unref() 0x4701c68: ref=-1 -src/adapter.c:btd_adapter_pincode_reply() hci0 addr 6C:0E:0D:DB:D1:16 - pinlen 0 -src/agent.c:agent_unref() 0x4701c68: ref=-2 -... ---- - src/agent.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/agent.c b/src/agent.c -index b292881..2ec3183 100644 ---- a/src/agent.c -+++ b/src/agent.c -@@ -428,6 +428,9 @@ static void pincode_reply(DBusPendingCall *call, void *user_data) - * is only called after a reply has been received */ - message = dbus_pending_call_steal_reply(call); - -+ /* Protect from the callback freeing the agent */ -+ agent_ref(agent); -+ - dbus_error_init(&err); - if (dbus_set_error_from_message(&err, message)) { - error("Agent %s replied with an error: %s, %s", -@@ -467,6 +470,7 @@ done: - dbus_pending_call_cancel(req->call); - agent->request = NULL; - agent_request_free(req, TRUE); -+ agent_unref(agent); - } - - static int pincode_request_new(struct agent_request *req, const char *device_path, --- -1.8.4.2 - diff --git a/bluez.spec b/bluez.spec index 3c5ee6a..fb150bf 100644 --- a/bluez.spec +++ b/bluez.spec @@ -2,8 +2,8 @@ Summary: Bluetooth utilities Name: bluez -Version: 5.11 -Release: 2%{?dist} +Version: 5.12 +Release: 1%{?dist} License: GPLv2+ Group: Applications/System URL: http://www.bluez.org/ @@ -11,17 +11,13 @@ URL: http://www.bluez.org/ Source0: http://www.kernel.org/pub/linux/bluetooth/bluez-%{version}.tar.xz Source1: bluez.gitignore -## 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 Patch4: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch Patch5: 0002-autopair-Don-t-handle-the-iCade.patch -Patch6: 0003-input-Fix-crash-when-SDP-record-isn-t-available.patch Patch7: 0004-agent-Assert-possible-infinite-loop.patch -Patch8: 0005-core-Fix-crash-due-to-agent-callback-freeing-the-age.patch BuildRequires: git BuildRequires: dbus-devel >= 0.90 @@ -233,6 +229,10 @@ mkdir -p $RPM_BUILD_ROOT/%{_libdir}/bluetooth/ /lib/udev/rules.d/97-hid2hci.rules %changelog +* Wed Dec 11 2013 Bastien Nocera 5.12-1 +- Update to 5.12 +- Sixaxis PS3 joypad support is now upstream + * Tue Dec 10 2013 Bastien Nocera 5.11-2 - Add crasher fixes (rhbz #1027365) diff --git a/playstation-peripheral-pugin-v5.x.patch b/playstation-peripheral-pugin-v5.x.patch deleted file mode 100644 index 222f023..0000000 --- a/playstation-peripheral-pugin-v5.x.patch +++ /dev/null @@ -1,1028 +0,0 @@ -From 76986f1d8d356ddd6a1c31190627ecbe8ab1d773 Mon Sep 17 00:00:00 2001 -From: Antonio Ospite -Date: Mon, 19 Sep 2011 18:15:40 +0200 -Subject: [PATCH 1/5] adapter: add a btd_adapter_get_default_address() call -X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE - -Add a new btd_* call to get the default adapter address as a string. - -This is meant to be used, for instance, by _external_ plugins which want -to know the default adapter address for some reason (e.g. to send it to -a device for some custom pairing scheme like in the case of Playstation -peripherals). - -External plugins can only use symbols marked as "global" in -src/bluetooth.ver, this patch avoids making global these symbols: - - adapter_get_address - bt_malloc - ba2str ---- - src/adapter.c | 17 +++++++++++++++++ - src/adapter.h | 1 + - 2 files changed, 18 insertions(+) - -diff --git a/src/adapter.c b/src/adapter.c -index 1250966..a7a2530 100644 ---- a/src/adapter.c -+++ b/src/adapter.c -@@ -224,6 +224,23 @@ struct btd_adapter *btd_adapter_get_default(void) - 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(adapter_get_address(adapter), str); -+ return str; -+} -+ - bool btd_adapter_is_default(struct btd_adapter *adapter) - { - if (!adapter) -diff --git a/src/adapter.h b/src/adapter.h -index 2de8730..ed99b55 100644 ---- a/src/adapter.h -+++ b/src/adapter.h -@@ -38,6 +38,7 @@ - struct btd_adapter; - - 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); - --- -1.7.10.4 - - -From 2321b3b669de2edc3a9be2e1980c4b1f5312e176 Mon Sep 17 00:00:00 2001 -From: Antonio Ospite -Date: Mon, 19 Sep 2011 18:13:57 +0200 -Subject: [PATCH 2/5] adapter: add a btd_create_stored_device() call -X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE - -Add a new btd_* call to add a new device to the database of known -devices. - -This is particularly useful to register Bluetooth devices using -a non-Bluetooth mechanism (e.g. USB-pairing in the case of Playstation -peripherals). - -The interface uses a btd_ prefix and relies only on native C types in -order to be more easily used by _external_ plugins. - -External plugins can only use symbols marked as "global" in -src/bluetooth.ver, this patch avoids making global these symbols: - - store_sdp_record - str2ba - adapter_get_device - device_set_name - device_set_temporary - device_set_trusted ---- - src/adapter.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/adapter.h | 11 +++++++++++ - 2 files changed, 63 insertions(+) - -diff --git a/src/adapter.c b/src/adapter.c -index a7a2530..ea3a739 100644 ---- a/src/adapter.c -+++ b/src/adapter.c -@@ -6318,3 +6318,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 = adapter_get_device(adapter, &dst, BDADDR_BREDR); -+ if (device == NULL) { -+ DBG("Failed to get the device"); -+ ret = -ENODEV; -+ goto out; -+ } -+ -+ if (name) -+ 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); -+ -+ device_set_temporary(device, FALSE); -+ -+ if (trusted) -+ device_set_trusted(device, TRUE); -+out: -+ return ret; -+} -diff --git a/src/adapter.h b/src/adapter.h -index ed99b55..2abc9ce 100644 ---- a/src/adapter.h -+++ b/src/adapter.h -@@ -214,3 +214,14 @@ gboolean btd_adapter_check_oob_handler(struct btd_adapter *adapter); - 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 *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); --- -1.7.10.4 - - -From bbdb42cb551fc8600025e2832cf6bf08fc51337e Mon Sep 17 00:00:00 2001 -From: Antonio Ospite -Date: Wed, 5 May 2010 13:43:09 +0200 -Subject: [PATCH 3/5] Add playstation-peripheral plugin: USB pairing and LEDs - settings -X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE - -Add a plugin which handles the connection of a Playstation peripheral, -when a new hidraw device is connected the plugin: - - - Filters udev events, and select the Playstation peripheral - - Sets the Master bluetooth address in the peripheral (USB pairing) - - Sets LEDs to match the joystick system number if needed - (for USB and BT) - - Adds the device to the database of the current default - adapter (BT association) - -Signed-off-by: Bastien Nocera -Signed-off-by: Antonio Ospite ---- - Makefile.am | 7 + - configure.ac | 10 + - plugins/playstation-peripheral-hid.c | 263 ++++++++++++++++++++++ - plugins/playstation-peripheral-hid.h | 10 + - plugins/playstation-peripheral.c | 401 ++++++++++++++++++++++++++++++++++ - 5 files changed, 691 insertions(+) - create mode 100644 plugins/playstation-peripheral-hid.c - create mode 100644 plugins/playstation-peripheral-hid.h - create mode 100644 plugins/playstation-peripheral.c - -diff --git a/Makefile.am b/Makefile.am -index 9d570fb..a78a8ba 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -112,6 +112,13 @@ builtin_nodist = - - include Makefile.plugins - -+if PLAYSTATION_PERIPHERAL_PLUGIN -+plugin_LTLIBRARIES += plugins/playstation-peripheral.la -+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@ -+endif -+ - if MAINTAINER_MODE - plugin_LTLIBRARIES += plugins/external-dummy.la - plugins_external_dummy_la_SOURCES = plugins/external-dummy.c -diff --git a/configure.ac b/configure.ac -index f3c58be..7e0cc0c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -229,6 +229,16 @@ AC_ARG_ENABLE(experimental, AC_HELP_STRING([--enable-experimental], - [enable_experimental=${enableval}]) - AM_CONDITIONAL(EXPERIMENTAL, test "${enable_experimental}" = "yes") - -+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 -diff --git a/plugins/playstation-peripheral-hid.c b/plugins/playstation-peripheral-hid.c -new file mode 100644 -index 0000000..9c5e530 ---- /dev/null -+++ b/plugins/playstation-peripheral-hid.c -@@ -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); -+} -diff --git a/plugins/playstation-peripheral-hid.h b/plugins/playstation-peripheral-hid.h -new file mode 100644 -index 0000000..ade8fa0 ---- /dev/null -+++ b/plugins/playstation-peripheral-hid.h -@@ -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 */ -diff --git a/plugins/playstation-peripheral.c b/plugins/playstation-peripheral.c -new file mode 100644 -index 0000000..9238e92 ---- /dev/null -+++ b/plugins/playstation-peripheral.c -@@ -0,0 +1,401 @@ -+/* -+ * 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) -+ 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) --- -1.7.10.4 - - -From 0b2c7efd2105f793170a8d0b90eaf49647315afb Mon Sep 17 00:00:00 2001 -From: Antonio Ospite -Date: Fri, 5 Aug 2011 13:06:27 +0200 -Subject: [PATCH 4/5] XXX: plugins/playstation-peripheral: Wait for the PS - button before setting the LEDs -X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE - -Wait for actual input events, that is PS button has been pressed, before -setting the LEDs to indicate the controller number. -This makes setting LEDs look like on the PS3. - -NOTE: This change is experimental, the logic is too simple and can fail when -multiple peripherals are handled. Don't squash it into other commits. ---- - plugins/playstation-peripheral.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/plugins/playstation-peripheral.c b/plugins/playstation-peripheral.c -index 9238e92..c7d4bdf 100644 ---- a/plugins/playstation-peripheral.c -+++ b/plugins/playstation-peripheral.c -@@ -318,8 +318,16 @@ static void handle_device_plug(struct udev_device *udevice) - free(adapter_bdaddr); - } - -- if (js_num > 0) -+ 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); - } --- -1.7.10.4 - - -From 8e72267e7af9fb223a6089e36d627d66b66924f9 Mon Sep 17 00:00:00 2001 -From: Antonio Ospite -Date: Mon, 10 Oct 2011 22:40:49 +0200 -Subject: [PATCH 5/5] XXX Add src/bluetoothd to plugins_playstation_peripheral - dependencies -X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE - -NOTE: this change can be useful during development when we change bluez code -but it is probably overkill for the final submission. Don't squash it into -other commits. ---- - Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Makefile.am b/Makefile.am -index a78a8ba..a14d678 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -114,6 +114,7 @@ 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@ --- -1.7.10.4 - diff --git a/sources b/sources index c4bb424..eb809d2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -8a2544d8c88e1f4bd3abe9525282b13c bluez-5.11.tar.xz +5d37e581107b3d6f91b81194a5006407 bluez-5.12.tar.xz