Update to 5.48

This commit is contained in:
Pete Walter 2017-12-29 10:31:52 +00:00
parent 020b1cfab2
commit 258c6a467d
13 changed files with 6 additions and 1714 deletions

View File

@ -1,48 +0,0 @@
From 8c23335a00bbd6f359702024698a24d45e3c653b Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Tue, 19 Nov 2013 14:11:39 +0100
Subject: [PATCH] autopair: Don't handle the iCade
We can't easily enter digits other than 1 through 4 (inclusive)
so leave it up to the agent to figure out a good passcode
for the iCade.
Note that we can not use the VID/PID of the device, as it is not
yet known at that point.
---
plugins/autopair.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/plugins/autopair.c b/plugins/autopair.c
index d44cf539b..a9d2a930a 100644
--- a/plugins/autopair.c
+++ b/plugins/autopair.c
@@ -60,13 +60,24 @@ static ssize_t autopair_pincb(struct btd_adapter *adapter,
{
char addr[18];
char pinstr[7];
+ char name[25];
uint32_t class;
ba2str(device_get_address(device), addr);
class = btd_device_get_class(device);
- DBG("device %s 0x%x", addr, class);
+ device_get_name(device, name, sizeof(name));
+ name[sizeof(name) - 1] = 0;
+
+ DBG("device '%s' (%s) class: 0x%x vid/pid: 0x%X/0x%X",
+ name, addr, class,
+ btd_device_get_vendor (device),
+ btd_device_get_product (device));
+
+ /* The iCade shouldn't use random PINs like normal keyboards */
+ if (name != NULL && strstr(name, "iCade") != NULL)
+ return 0;
/* This is a class-based pincode guesser. Ignore devices with an
* unknown class.
--
2.14.1

View File

@ -1,362 +0,0 @@
From 94149e19844c3344d1cdd57c24676a0c96b9c8a1 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 19:59:20 +0200
Subject: [PATCH 1/9] plugins/sixaxis: Remove LEDs handling
It's done in the kernel since 2014 in linux kernel commit
8025087acf9d2b941bae93b3e0967560e7e03e87
---
plugins/sixaxis.c | 295 +-----------------------------------------------------
1 file changed, 5 insertions(+), 290 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 7e3c950b4..7d3a8f3ac 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -71,17 +71,6 @@ static const struct {
},
};
-struct leds_data {
- char *syspath_prefix;
- uint8_t bitmap;
-};
-
-static void leds_data_destroy(struct leds_data *data)
-{
- free(data->syspath_prefix);
- free(data);
-}
-
static struct udev *ctx = NULL;
static struct udev_monitor *monitor = NULL;
static guint watch_id = 0;
@@ -146,115 +135,6 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
return ret;
}
-static uint8_t calc_leds_bitmap(int number)
-{
- uint8_t bitmap = 0;
-
- /* TODO we could support up to 10 (1 + 2 + 3 + 4) */
- if (number > 7)
- return bitmap;
-
- if (number > 4) {
- bitmap |= 0x10;
- number -= 4;
- }
-
- bitmap |= 0x01 << number;
-
- return bitmap;
-}
-
-static void set_leds_hidraw(int fd, uint8_t leds_bitmap)
-{
- /*
- * the total time the led is active (0xff means forever)
- * | duty_length: cycle time in deciseconds (0 - "blink very fast")
- * | | ??? (Maybe a phase shift or duty_length multiplier?)
- * | | | % of duty_length led is off (0xff means 100%)
- * | | | | % of duty_length led is on (0xff means 100%)
- * | | | | |
- * 0xff, 0x27, 0x10, 0x00, 0x32,
- */
- uint8_t leds_report[] = {
- 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, /* rumble values TBD */
- 0x00, 0x00, 0x00, 0x00, 0x00, /* LED_1=0x02, LED_2=0x04 ... */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
- 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- int ret;
-
- leds_report[10] = leds_bitmap;
-
- ret = write(fd, leds_report, sizeof(leds_report));
- if (ret == sizeof(leds_report))
- return;
-
- if (ret < 0)
- error("sixaxis: failed to set LEDS (%s)", strerror(errno));
- else
- error("sixaxis: failed to set LEDS (%d bytes written)", ret);
-}
-
-static bool set_leds_sysfs(struct leds_data *data)
-{
- int i;
-
- if (!data->syspath_prefix)
- return false;
-
- /* start from 1, LED0 is never used */
- for (i = 1; i <= 4; i++) {
- char path[PATH_MAX] = { 0 };
- char buf[2] = { 0 };
- int fd;
- int ret;
-
- snprintf(path, PATH_MAX, "%s%d/brightness",
- data->syspath_prefix, i);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- error("sixaxis: cannot open %s (%s)", path,
- strerror(errno));
- return false;
- }
-
- buf[0] = '0' + !!(data->bitmap & (1 << i));
- ret = write(fd, buf, sizeof(buf));
- close(fd);
- if (ret != sizeof(buf))
- return false;
- }
-
- return true;
-}
-
-static gboolean setup_leds(GIOChannel *channel, GIOCondition cond,
- gpointer user_data)
-{
- struct leds_data *data = user_data;
-
- if (!data)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
- goto out;
-
- if(!set_leds_sysfs(data)) {
- int fd = g_io_channel_unix_get_fd(channel);
- set_leds_hidraw(fd, data->bitmap);
- }
-
-out:
- leds_data_destroy(data);
-
- return FALSE;
-}
-
static bool setup_device(int fd, int index, struct btd_adapter *adapter)
{
char device_addr[18], master_addr[18], adapter_addr[18];
@@ -269,8 +149,7 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
return false;
/* This can happen if controller was plugged while already connected
- * eg. to charge up battery.
- * Don't set LEDs in that case, hence return false */
+ * eg. to charge up battery. */
device = btd_adapter_find_device(adapter, &device_bdaddr,
BDADDR_BREDR);
if (device && btd_device_is_connected(device))
@@ -307,152 +186,6 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
return true;
}
-static int get_js_number(struct udev_device *udevice)
-{
- struct udev_list_entry *devices, *dev_list_entry;
- struct udev_enumerate *enumerate;
- struct udev_device *hid_parent;
- const char *hidraw_node;
- const char *hid_id;
- int number = 0;
-
- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
- "hid", NULL);
-
- /*
- * Look for HID_UNIQ first for the correct behavior via BT, if
- * HID_UNIQ is not available it means the USB bus is being used and we
- * can rely on HID_PHYS.
- */
- hid_id = udev_device_get_property_value(hid_parent, "HID_UNIQ");
- if (!hid_id)
- hid_id = udev_device_get_property_value(hid_parent,
- "HID_PHYS");
-
- hidraw_node = udev_device_get_devnode(udevice);
- if (!hid_id || !hidraw_node)
- return 0;
-
- enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
- udev_enumerate_add_match_sysname(enumerate, "js*");
- udev_enumerate_scan_devices(enumerate);
- devices = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(dev_list_entry, devices) {
- struct udev_device *input_parent;
- struct udev_device *js_dev;
- const char *input_id;
- const char *devname;
-
- devname = udev_list_entry_get_name(dev_list_entry);
- js_dev = udev_device_new_from_syspath(
- udev_device_get_udev(udevice),
- devname);
-
- input_parent = udev_device_get_parent_with_subsystem_devtype(
- js_dev, "input", NULL);
- if (!input_parent)
- goto next;
-
- /* check if this is the joystick relative to the hidraw device
- * above */
- input_id = udev_device_get_sysattr_value(input_parent, "uniq");
-
- /*
- * A strlen() check is needed because input device over USB
- * have the UNIQ attribute defined but with an empty value.
- */
- if (!input_id || strlen(input_id) == 0)
- input_id = udev_device_get_sysattr_value(input_parent,
- "phys");
-
- if (!input_id)
- goto next;
-
- if (!strcmp(input_id, hid_id)) {
- number = atoi(udev_device_get_sysnum(js_dev));
-
- /* joystick numbers start from 0, leds from 1 */
- number++;
-
- udev_device_unref(js_dev);
- break;
- }
-next:
- udev_device_unref(js_dev);
- }
-
- udev_enumerate_unref(enumerate);
-
- return number;
-}
-
-static char *get_leds_syspath_prefix(struct udev_device *udevice)
-{
- struct udev_list_entry *dev_list_entry;
- struct udev_enumerate *enumerate;
- struct udev_device *hid_parent;
- const char *syspath;
- char *syspath_prefix;
-
- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
- "hid", NULL);
-
- enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
- udev_enumerate_add_match_parent(enumerate, hid_parent);
- udev_enumerate_add_match_subsystem(enumerate, "leds");
- udev_enumerate_scan_devices(enumerate);
-
- dev_list_entry = udev_enumerate_get_list_entry(enumerate);
- if (!dev_list_entry) {
- syspath_prefix = NULL;
- goto out;
- }
-
- syspath = udev_list_entry_get_name(dev_list_entry);
-
- /*
- * All the sysfs paths of the LEDs have the same structure, just the
- * number changes, so strip it and store only the common prefix.
- *
- * Subtracting 1 here means assuming that the LED number is a single
- * digit, this is safe as the kernel driver only exposes 4 LEDs.
- */
- syspath_prefix = strndup(syspath, strlen(syspath) - 1);
-
-out:
- udev_enumerate_unref(enumerate);
-
- return syspath_prefix;
-}
-
-static struct leds_data *get_leds_data(struct udev_device *udevice)
-{
- struct leds_data *data;
- int number;
-
- number = get_js_number(udevice);
- DBG("number %d", number);
-
- data = malloc0(sizeof(*data));
- if (!data)
- return NULL;
-
- data->bitmap = calc_leds_bitmap(number);
- if (data->bitmap == 0) {
- leds_data_destroy(data);
- return NULL;
- }
-
- /*
- * It's OK if this fails, set_leds_hidraw() will be used in
- * case data->syspath_prefix is NULL.
- */
- data->syspath_prefix = get_leds_syspath_prefix(udevice);
-
- return data;
-}
-
static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
{
struct udev_device *hid_parent;
@@ -481,7 +214,6 @@ static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
static void device_added(struct udev_device *udevice)
{
struct btd_adapter *adapter;
- GIOChannel *io;
uint16_t bus;
int index;
int fd;
@@ -493,6 +225,8 @@ static void device_added(struct udev_device *udevice)
index = get_supported_device(udevice, &bus);
if (index < 0)
return;
+ if (bus != BUS_USB)
+ return;
info("sixaxis: compatible device connected: %s (%04X:%04X)",
devices[index].name, devices[index].vid,
@@ -502,27 +236,8 @@ static void device_added(struct udev_device *udevice)
if (fd < 0)
return;
- io = g_io_channel_unix_new(fd);
-
- switch (bus) {
- case BUS_USB:
- if (!setup_device(fd, index, adapter))
- break;
-
- /* fall through */
- case BUS_BLUETOOTH:
- /* wait for events before setting leds */
- g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- setup_leds, get_leds_data(udevice));
-
- break;
- default:
- DBG("uknown bus type (%u)", bus);
- break;
- }
-
- g_io_channel_set_close_on_unref(io, TRUE);
- g_io_channel_unref(io);
+ setup_device(fd, index, adapter);
+ close(fd);
}
static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
--
2.14.1

View File

@ -1,147 +0,0 @@
From 61ca4a50c8d03b00e6cb00ac6f6fee64fa310ff5 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Tue, 7 Jul 2015 15:45:26 +0200
Subject: [PATCH 2/9] adapter: Add btd_request_authorization_cable_configured()
Add btd_request_authorization_cable_configured() function to allow
cable configured devices to ask the user straight away about whether the
device should be allowed to connect to the computer.
This allows us to ask the user at the time of the USB connection and
initial setup, rather than when the first Bluetooth connection is made.
The fact that the device might not be connected to the adapter when
this event is triggered is mentioned in the Agent API docs.
---
doc/agent-api.txt | 5 ++++-
src/adapter.c | 42 ++++++++++++++++++++++++++++++++++++------
src/adapter.h | 2 ++
3 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/doc/agent-api.txt b/doc/agent-api.txt
index 801ccb665..0d9347cab 100644
--- a/doc/agent-api.txt
+++ b/doc/agent-api.txt
@@ -163,7 +163,10 @@ Methods void Release()
This method gets called to request the user to
authorize an incoming pairing attempt which
would in other circumstances trigger the just-works
- model.
+ model, or when the user plugged in a device that
+ implements cable pairing. In the latter case, the
+ device would not be connected to the adapter via
+ Bluetooth yet.
Possible errors: org.bluez.Error.Rejected
org.bluez.Error.Canceled
diff --git a/src/adapter.c b/src/adapter.c
index a571b1870..b24b73e30 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -265,6 +265,11 @@ struct btd_adapter {
bool is_default; /* true if adapter is default one */
};
+typedef enum {
+ ADAPTER_AUTHORIZE_DISCONNECTED = 0,
+ ADAPTER_AUTHORIZE_CHECK_CONNECTED
+} adapter_authorize_type;
+
static struct btd_adapter *btd_adapter_lookup(uint16_t index)
{
GList *list;
@@ -6088,8 +6093,9 @@ static void svc_complete(struct btd_device *dev, int err, void *user_data)
}
static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
- const char *uuid, service_auth_cb cb,
- void *user_data)
+ const char *uuid,
+ adapter_authorize_type check_for_connection,
+ service_auth_cb cb, void *user_data)
{
struct service_auth *auth;
struct btd_device *device;
@@ -6105,7 +6111,7 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
}
/* Device connected? */
- if (!g_slist_find(adapter->connections, device))
+ if (check_for_connection && !g_slist_find(adapter->connections, device))
btd_error(adapter->dev_id,
"Authorization request for non-connected device!?");
@@ -6119,7 +6125,12 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
auth->device = device;
auth->adapter = adapter;
auth->id = ++id;
- auth->svc_id = device_wait_for_svc_complete(device, svc_complete, auth);
+ if (check_for_connection)
+ auth->svc_id = device_wait_for_svc_complete(device, svc_complete, auth);
+ else {
+ if (adapter->auth_idle_id == 0)
+ adapter->auth_idle_id = g_idle_add(process_auth_queue, adapter);
+ }
g_queue_push_tail(adapter->auths, auth);
@@ -6138,7 +6149,8 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
if (!adapter)
return 0;
- return adapter_authorize(adapter, dst, uuid, cb, user_data);
+ return adapter_authorize(adapter, dst, uuid,
+ ADAPTER_AUTHORIZE_CHECK_CONNECTED, cb, user_data);
}
for (l = adapters; l != NULL; l = g_slist_next(l)) {
@@ -6146,7 +6158,8 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
adapter = l->data;
- id = adapter_authorize(adapter, dst, uuid, cb, user_data);
+ id = adapter_authorize(adapter, dst, uuid,
+ ADAPTER_AUTHORIZE_CHECK_CONNECTED, cb, user_data);
if (id != 0)
return id;
}
@@ -6154,6 +6167,23 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
return 0;
}
+guint btd_request_authorization_cable_configured(const bdaddr_t *src, const bdaddr_t *dst,
+ const char *uuid, service_auth_cb cb,
+ void *user_data)
+{
+ struct btd_adapter *adapter;
+
+ if (bacmp(src, BDADDR_ANY) == 0)
+ return 0;
+
+ adapter = adapter_find(src);
+ if (!adapter)
+ return 0;
+
+ return adapter_authorize(adapter, dst, uuid,
+ ADAPTER_AUTHORIZE_DISCONNECTED, cb, user_data);
+}
+
static struct service_auth *find_authorization(guint id)
{
GSList *l;
diff --git a/src/adapter.h b/src/adapter.h
index f9178d59e..a85327cd1 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -120,6 +120,8 @@ int btd_register_adapter_driver(struct btd_adapter_driver *driver);
void btd_unregister_adapter_driver(struct btd_adapter_driver *driver);
guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
const char *uuid, service_auth_cb cb, void *user_data);
+guint btd_request_authorization_cable_configured(const bdaddr_t *src, const bdaddr_t *dst,
+ const char *uuid, service_auth_cb cb, void *user_data);
int btd_cancel_authorization(guint id);
int btd_adapter_restore_powered(struct btd_adapter *adapter);
--
2.14.1

View File

@ -1,32 +0,0 @@
From 9b760ecfa7d0f96bbac3ff606fbd560d58b2d1a6 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Thu, 24 Aug 2017 16:58:46 +0200
Subject: [PATCH 2/4] obexd: Fix compilation error on F27
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In file included from obexd/plugins/mas.c:41:0:
./obexd/src/obex.h:37:1: error: unknown type name ssize_t; did you mean size_t?
ssize_t obex_get_size(struct obex_session *os);
^~~~~~~
---
obexd/src/obex.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index fc1674755..67593f11b 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -22,6 +22,8 @@
*
*/
+#include <unistd.h>
+
#define OBJECT_SIZE_UNKNOWN -1
#define OBJECT_SIZE_DELETE -2
--
2.14.1

View File

@ -1,166 +0,0 @@
From 8bb84509033bd0f3251d795627f1d9966edc1a18 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Tue, 7 Jul 2015 15:42:25 +0200
Subject: [PATCH 3/9] sixaxis: Ask user whether cable configuration should be
allowed
Previously, users doing cable configuration of Sixaxis PS3 controllers
would only get asked whether a device was allowed to connect to the
computer when switching it to Bluetooth mode: unplugging it, and
pressing the PS button.
Instead, we should ask the user straight away, through the agent,
whether the pad should be allowed to connect.
This makes it easier to setup those devices, while keeping security.
---
plugins/sixaxis.c | 83 +++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 63 insertions(+), 20 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 7d3a8f3ac..c8305d52f 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -44,6 +44,7 @@
#include "src/adapter.h"
#include "src/device.h"
+#include "src/agent.h"
#include "src/plugin.h"
#include "src/log.h"
#include "src/shared/util.h"
@@ -71,6 +72,13 @@ static const struct {
},
};
+struct authentication_closure {
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+ int fd;
+ char device_addr[18];
+};
+
static struct udev *ctx = NULL;
static struct udev_monitor *monitor = NULL;
static guint watch_id = 0;
@@ -135,19 +143,51 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
return ret;
}
+static void agent_auth_cb(DBusError *derr,
+ void *user_data)
+{
+ struct authentication_closure *closure = user_data;
+ char master_addr[18], adapter_addr[18];
+ bdaddr_t master_bdaddr;
+ const bdaddr_t *adapter_bdaddr;
+
+ if (derr != NULL) {
+ DBG("Agent replied negatively, removing temporary device");
+ goto error;
+ }
+
+ btd_device_set_temporary(closure->device, false);
+
+ if (get_master_bdaddr(closure->fd, &master_bdaddr) < 0)
+ goto error;
+
+ adapter_bdaddr = btd_adapter_get_address(closure->adapter);
+ if (bacmp(adapter_bdaddr, &master_bdaddr)) {
+ if (set_master_bdaddr(closure->fd, adapter_bdaddr) < 0)
+ goto error;
+ }
+
+ ba2str(&master_bdaddr, master_addr);
+ ba2str(adapter_bdaddr, adapter_addr);
+ DBG("remote %s old_master %s new_master %s",
+ closure->device_addr, master_addr, adapter_addr);
+
+error:
+ close(closure->fd);
+ g_free(closure);
+}
+
static bool setup_device(int fd, int index, struct btd_adapter *adapter)
{
- char device_addr[18], master_addr[18], adapter_addr[18];
- bdaddr_t device_bdaddr, master_bdaddr;
+ char device_addr[18];
+ bdaddr_t device_bdaddr;
const bdaddr_t *adapter_bdaddr;
struct btd_device *device;
+ struct authentication_closure *closure;
if (get_device_bdaddr(fd, &device_bdaddr) < 0)
return false;
- if (get_master_bdaddr(fd, &master_bdaddr) < 0)
- return false;
-
/* This can happen if controller was plugged while already connected
* eg. to charge up battery. */
device = btd_adapter_find_device(adapter, &device_bdaddr,
@@ -155,25 +195,14 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
if (device && btd_device_is_connected(device))
return false;
- adapter_bdaddr = btd_adapter_get_address(adapter);
-
- if (bacmp(adapter_bdaddr, &master_bdaddr)) {
- if (set_master_bdaddr(fd, adapter_bdaddr) < 0)
- return false;
- }
-
ba2str(&device_bdaddr, device_addr);
- ba2str(&master_bdaddr, master_addr);
- ba2str(adapter_bdaddr, adapter_addr);
- DBG("remote %s old_master %s new_master %s",
- device_addr, master_addr, adapter_addr);
device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR);
if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID,
(GCompareFunc)strcasecmp)) {
DBG("device %s already known, skipping", device_addr);
- return true;
+ return false;
}
info("sixaxis: setting up new device");
@@ -181,7 +210,20 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
btd_device_device_set_name(device, devices[index].name);
btd_device_set_pnpid(device, devices[index].source, devices[index].vid,
devices[index].pid, devices[index].version);
- btd_device_set_temporary(device, false);
+ btd_device_set_temporary(device, true);
+
+ closure = g_try_new0(struct authentication_closure, 1);
+ if (!closure) {
+ btd_adapter_remove_device(adapter, device);
+ return false;
+ }
+ closure->adapter = adapter;
+ closure->device = device;
+ closure->fd = fd;
+ memcpy(&closure->device_addr, device_addr, sizeof(device_addr));
+ adapter_bdaddr = btd_adapter_get_address(adapter);
+ btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr,
+ HID_UUID, agent_auth_cb, closure);
return true;
}
@@ -236,8 +278,9 @@ static void device_added(struct udev_device *udevice)
if (fd < 0)
return;
- setup_device(fd, index, adapter);
- close(fd);
+ /* Only close the fd if an authentication is not pending */
+ if (!setup_device(fd, index, adapter))
+ close(fd);
}
static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
--
2.14.1

View File

@ -1,259 +0,0 @@
From d3cd88dc5f83e4b23170288eddecd665ad1742eb Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 18:59:06 +0200
Subject: [PATCH 4/9] plugins/sixaxis: Move device discovery to shared header
Move the struct containing the Sixaxis-compatible devices to a
header shared with the input profiles code, so as to reduce device
declaration.
Adding support for new devices should be as easy as adding the device's
declaration in profiles/input/sixaxis.h
---
plugins/sixaxis.c | 82 +++++++++++++++++++++-------------------------
profiles/input/sixaxis.h | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+), 45 deletions(-)
create mode 100644 profiles/input/sixaxis.h
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index c8305d52f..3e8ac06ca 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -48,29 +48,7 @@
#include "src/plugin.h"
#include "src/log.h"
#include "src/shared/util.h"
-
-static const struct {
- const char *name;
- uint16_t source;
- uint16_t vid;
- uint16_t pid;
- uint16_t version;
-} devices[] = {
- {
- .name = "Sony PLAYSTATION(R)3 Controller",
- .source = 0x0002,
- .vid = 0x054c,
- .pid = 0x0268,
- .version = 0x0000,
- },
- {
- .name = "Navigation Controller",
- .source = 0x0002,
- .vid = 0x054c,
- .pid = 0x042f,
- .version = 0x0000,
- },
-};
+#include "profiles/input/sixaxis.h"
struct authentication_closure {
struct btd_adapter *adapter;
@@ -177,7 +155,13 @@ error:
g_free(closure);
}
-static bool setup_device(int fd, int index, struct btd_adapter *adapter)
+static bool setup_device(int fd,
+ const char *name,
+ uint16_t source,
+ uint16_t vid,
+ uint16_t pid,
+ uint16_t version,
+ struct btd_adapter *adapter)
{
char device_addr[18];
bdaddr_t device_bdaddr;
@@ -207,9 +191,8 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
info("sixaxis: setting up new device");
- btd_device_device_set_name(device, devices[index].name);
- btd_device_set_pnpid(device, devices[index].source, devices[index].vid,
- devices[index].pid, devices[index].version);
+ btd_device_device_set_name(device, name);
+ btd_device_set_pnpid(device, source, vid, pid, version);
btd_device_set_temporary(device, true);
closure = g_try_new0(struct authentication_closure, 1);
@@ -228,12 +211,16 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
return true;
}
-static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
+static CablePairingType get_pairing_type_for_device(struct udev_device *udevice,
+ uint16_t *bus,
+ uint16_t *vid,
+ uint16_t *pid,
+ char **name,
+ uint16_t *source,
+ uint16_t *version)
{
struct udev_device *hid_parent;
- uint16_t vid, pid;
const char *hid_id;
- guint i;
hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
"hid", NULL);
@@ -242,45 +229,50 @@ static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
hid_id = udev_device_get_property_value(hid_parent, "HID_ID");
- if (sscanf(hid_id, "%hx:%hx:%hx", bus, &vid, &pid) != 3)
+ if (sscanf(hid_id, "%hx:%hx:%hx", bus, vid, pid) != 3)
return -1;
- for (i = 0; i < G_N_ELEMENTS(devices); i++) {
- if (devices[i].vid == vid && devices[i].pid == pid)
- return i;
- }
-
- return -1;
+ return get_pairing_type(*vid, *pid, name, source, version);
}
static void device_added(struct udev_device *udevice)
{
struct btd_adapter *adapter;
- uint16_t bus;
- int index;
+ uint16_t bus, vid, pid, source, version;
+ char *name = NULL;
+ CablePairingType type;
int fd;
adapter = btd_adapter_get_default();
if (!adapter)
return;
- index = get_supported_device(udevice, &bus);
- if (index < 0)
+ type = get_pairing_type_for_device(udevice,
+ &bus,
+ &vid,
+ &pid,
+ &name,
+ &source,
+ &version);
+ if (type != CABLE_PAIRING_SIXAXIS)
return;
if (bus != BUS_USB)
return;
info("sixaxis: compatible device connected: %s (%04X:%04X)",
- devices[index].name, devices[index].vid,
- devices[index].pid);
+ name, vid, pid);
fd = open(udev_device_get_devnode(udevice), O_RDWR);
- if (fd < 0)
+ if (fd < 0) {
+ g_free(name);
return;
+ }
/* Only close the fd if an authentication is not pending */
- if (!setup_device(fd, index, adapter))
+ if (!setup_device(fd, name, source, vid, pid, version, adapter))
close(fd);
+
+ g_free(name);
}
static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h
new file mode 100644
index 000000000..0b3c4e397
--- /dev/null
+++ b/profiles/input/sixaxis.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2009,2017 Bastien Nocera <hadess@hadess.net>
+ * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
+ * Copyright (C) 2013 Szymon Janc <szymon.janc@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef _SIXAXIS_H_
+#define _SIXAXIS_H_
+
+typedef enum {
+ CABLE_PAIRING_UNSUPPORTED = 0,
+ CABLE_PAIRING_SIXAXIS,
+} CablePairingType;
+
+static inline CablePairingType get_pairing_type(uint16_t vid,
+ uint16_t pid,
+ char **name,
+ uint16_t *source,
+ uint16_t *version)
+{
+ static const struct {
+ const char *name;
+ uint16_t source;
+ uint16_t vid;
+ uint16_t pid;
+ uint16_t version;
+ CablePairingType type;
+ } devices[] = {
+ {
+ .name = "Sony PLAYSTATION(R)3 Controller",
+ .source = 0x0002,
+ .vid = 0x054c,
+ .pid = 0x0268,
+ .version = 0x0000,
+ .type = CABLE_PAIRING_SIXAXIS,
+ },
+ {
+ .name = "Navigation Controller",
+ .source = 0x0002,
+ .vid = 0x054c,
+ .pid = 0x042f,
+ .version = 0x0000,
+ .type = CABLE_PAIRING_SIXAXIS,
+ },
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS(devices); i++) {
+ if (devices[i].vid != vid)
+ continue;
+ if (devices[i].pid != pid)
+ continue;
+
+ if (name)
+ *name = g_strdup(devices[i].name);
+ if (source)
+ *source = devices[i].source;
+ if (version)
+ *version = devices[i].version;
+ return devices[i].type;
+ }
+
+ return CABLE_PAIRING_UNSUPPORTED;
+}
+
+#endif /* _SIXAXIS_H_ */
--
2.14.1

View File

@ -1,56 +0,0 @@
From 493f46056fba02eb767fc881089de2b204b9166a Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 19:04:16 +0200
Subject: [PATCH 5/9] profiles/input: Use sixaxis header to simplify device
detection
Use the shared header to recognise whether a device is a Sixaxis device
or not.
---
profiles/input/server.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/profiles/input/server.c b/profiles/input/server.c
index eb3fcf843..121c334d3 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -43,6 +43,7 @@
#include "src/device.h"
#include "src/profile.h"
+#include "sixaxis.h"
#include "device.h"
#include "server.h"
@@ -123,6 +124,7 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
{
struct btd_device *device;
uint16_t vid, pid;
+ CablePairingType type;
device = btd_adapter_find_device(adapter_find(src), dst, BDADDR_BREDR);
if (!device)
@@ -131,18 +133,14 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
vid = btd_device_get_vendor(device);
pid = btd_device_get_product(device);
- /* DualShock 3 */
- if (vid == 0x054c && pid == 0x0268)
+ type = get_pairing_type(vid, pid, NULL, NULL, NULL);
+ if (type == CABLE_PAIRING_SIXAXIS)
return true;
/* DualShock 4 */
if (vid == 0x054c && pid == 0x05c4)
return true;
- /* Navigation Controller */
- if (vid == 0x054c && pid == 0x042f)
- return true;
-
return false;
}
--
2.14.1

View File

@ -1,67 +0,0 @@
From f19baae3e53137522f4da94118af695b4213f657 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 19:07:18 +0200
Subject: [PATCH 6/9] profiles/input: Add DS4 devices to the shared header
And simplify the detection code in server.c some more.
---
profiles/input/server.c | 7 ++-----
profiles/input/sixaxis.h | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/profiles/input/server.c b/profiles/input/server.c
index 121c334d3..ef428fefe 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -134,11 +134,8 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
pid = btd_device_get_product(device);
type = get_pairing_type(vid, pid, NULL, NULL, NULL);
- if (type == CABLE_PAIRING_SIXAXIS)
- return true;
-
- /* DualShock 4 */
- if (vid == 0x054c && pid == 0x05c4)
+ if (type == CABLE_PAIRING_SIXAXIS ||
+ type == CABLE_PAIRING_DS4)
return true;
return false;
diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h
index 0b3c4e397..17a7dc3f7 100644
--- a/profiles/input/sixaxis.h
+++ b/profiles/input/sixaxis.h
@@ -29,6 +29,7 @@
typedef enum {
CABLE_PAIRING_UNSUPPORTED = 0,
CABLE_PAIRING_SIXAXIS,
+ CABLE_PAIRING_DS4,
} CablePairingType;
static inline CablePairingType get_pairing_type(uint16_t vid,
@@ -61,6 +62,22 @@ static inline CablePairingType get_pairing_type(uint16_t vid,
.version = 0x0000,
.type = CABLE_PAIRING_SIXAXIS,
},
+ {
+ .name = "Wireless Controller",
+ .source = 0x0002,
+ .vid = 0x054c,
+ .pid = 0x05c4,
+ .version = 0x0001,
+ .type = CABLE_PAIRING_DS4,
+ },
+ {
+ .name = "Wireless Controller",
+ .source = 0x0002,
+ .vid = 0x054c,
+ .pid = 0x09cc,
+ .version = 0x0001,
+ .type = CABLE_PAIRING_DS4,
+ },
};
guint i;
--
2.14.1

View File

@ -1,129 +0,0 @@
From 55653a27c21dbab1e63bdec08a63771ea8b8cb1f Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 25 Aug 2017 19:29:04 +0200
Subject: [PATCH 7/9] plugins/sixaxis: Rename sixaxis specific functions
And provide wrappers to prepare for the addition of other device types.
---
plugins/sixaxis.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 3e8ac06ca..b62834d72 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -55,13 +55,14 @@ struct authentication_closure {
struct btd_device *device;
int fd;
char device_addr[18];
+ CablePairingType type;
};
static struct udev *ctx = NULL;
static struct udev_monitor *monitor = NULL;
static guint watch_id = 0;
-static int get_device_bdaddr(int fd, bdaddr_t *bdaddr)
+static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
{
uint8_t buf[18];
int ret;
@@ -82,7 +83,14 @@ static int get_device_bdaddr(int fd, bdaddr_t *bdaddr)
return 0;
}
-static int get_master_bdaddr(int fd, bdaddr_t *bdaddr)
+static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
+{
+ if (type == CABLE_PAIRING_SIXAXIS)
+ return sixaxis_get_device_bdaddr(fd, bdaddr);
+ return -1;
+}
+
+static int sixaxis_get_master_bdaddr(int fd, bdaddr_t *bdaddr)
{
uint8_t buf[8];
int ret;
@@ -103,7 +111,14 @@ static int get_master_bdaddr(int fd, bdaddr_t *bdaddr)
return 0;
}
-static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
+static int get_master_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
+{
+ if (type == CABLE_PAIRING_SIXAXIS)
+ return sixaxis_get_master_bdaddr(fd, bdaddr);
+ return -1;
+}
+
+static int sixaxis_set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
{
uint8_t buf[8];
int ret;
@@ -121,6 +136,14 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
return ret;
}
+static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr,
+ CablePairingType type)
+{
+ if (type == CABLE_PAIRING_SIXAXIS)
+ return sixaxis_set_master_bdaddr(fd, bdaddr);
+ return -1;
+}
+
static void agent_auth_cb(DBusError *derr,
void *user_data)
{
@@ -136,12 +159,12 @@ static void agent_auth_cb(DBusError *derr,
btd_device_set_temporary(closure->device, false);
- if (get_master_bdaddr(closure->fd, &master_bdaddr) < 0)
+ if (get_master_bdaddr(closure->fd, &master_bdaddr, closure->type) < 0)
goto error;
adapter_bdaddr = btd_adapter_get_address(closure->adapter);
if (bacmp(adapter_bdaddr, &master_bdaddr)) {
- if (set_master_bdaddr(closure->fd, adapter_bdaddr) < 0)
+ if (set_master_bdaddr(closure->fd, adapter_bdaddr, closure->type) < 0)
goto error;
}
@@ -161,6 +184,7 @@ static bool setup_device(int fd,
uint16_t vid,
uint16_t pid,
uint16_t version,
+ CablePairingType type,
struct btd_adapter *adapter)
{
char device_addr[18];
@@ -169,7 +193,7 @@ static bool setup_device(int fd,
struct btd_device *device;
struct authentication_closure *closure;
- if (get_device_bdaddr(fd, &device_bdaddr) < 0)
+ if (get_device_bdaddr(fd, &device_bdaddr, type) < 0)
return false;
/* This can happen if controller was plugged while already connected
@@ -203,6 +227,7 @@ static bool setup_device(int fd,
closure->adapter = adapter;
closure->device = device;
closure->fd = fd;
+ closure->type = type;
memcpy(&closure->device_addr, device_addr, sizeof(device_addr));
adapter_bdaddr = btd_adapter_get_address(adapter);
btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr,
@@ -269,7 +294,7 @@ static void device_added(struct udev_device *udevice)
}
/* Only close the fd if an authentication is not pending */
- if (!setup_device(fd, name, source, vid, pid, version, adapter))
+ if (!setup_device(fd, name, source, vid, pid, version, type, adapter))
close(fd);
g_free(name);
--
2.14.1

View File

@ -1,140 +0,0 @@
From 84191be1d4903a92fd0e8f79b15335f0c9abf925 Mon Sep 17 00:00:00 2001
From: Juha Kuikka <juha.kuikka@gmail.com>
Date: Fri, 25 Aug 2017 19:35:19 +0200
Subject: [PATCH 8/9] plugins/sixaxis: Add support for DualShock 4/PS4 cable
pairing
This patch adds support for "pairing" a Dualshock4 controller over USB
into the sixaxis plugin, similarly to what the Sixaxis/PS3 controller
supported.
Actual bonding happens on first connection, but the device will be
marked as trusted when the agent replies.
This patch is based on DS4 supprt for sixpair tool by t0xicCode:
https://github.com/t0xicCode/sixpair/commit/975c38cb6cd61a2f0be350714f0f64cef5f0432c
---
plugins/sixaxis.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index b62834d72..eb15acb92 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -83,10 +83,34 @@ static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
return 0;
}
+static int ds4_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+ uint8_t buf[7];
+ int ret;
+
+ memset(buf, 0, sizeof(buf));
+
+ buf[0] = 0x81;
+
+ ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+ if (ret < 0) {
+ error("ds4: failed to read device address (%s)",
+ strerror(errno));
+ return ret;
+ }
+
+ /* address is little-endian on DS4 */
+ bacpy(bdaddr, (bdaddr_t*) (buf + 1));
+
+ return 0;
+}
+
static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
{
if (type == CABLE_PAIRING_SIXAXIS)
return sixaxis_get_device_bdaddr(fd, bdaddr);
+ else if (type == CABLE_PAIRING_DS4)
+ return ds4_get_device_bdaddr(fd, bdaddr);
return -1;
}
@@ -111,10 +135,34 @@ static int sixaxis_get_master_bdaddr(int fd, bdaddr_t *bdaddr)
return 0;
}
+static int ds4_get_master_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+ uint8_t buf[16];
+ int ret;
+
+ memset(buf, 0, sizeof(buf));
+
+ buf[0] = 0x12;
+
+ ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+ if (ret < 0) {
+ error("ds4: failed to read master address (%s)",
+ strerror(errno));
+ return ret;
+ }
+
+ /* address is little-endian on DS4 */
+ bacpy(bdaddr, (bdaddr_t*) (buf + 10));
+
+ return 0;
+}
+
static int get_master_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
{
if (type == CABLE_PAIRING_SIXAXIS)
return sixaxis_get_master_bdaddr(fd, bdaddr);
+ else if (type == CABLE_PAIRING_DS4)
+ return ds4_get_master_bdaddr(fd, bdaddr);
return -1;
}
@@ -136,11 +184,33 @@ static int sixaxis_set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
return ret;
}
+static int ds4_set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
+{
+ uint8_t buf[23];
+ int ret;
+
+ buf[0] = 0x13;
+ bacpy((bdaddr_t*) (buf + 1), bdaddr);
+ /* TODO: we could put the key here but
+ there is no way to force a re-loading
+ of link keys to the kernel from here. */
+ memset(buf + 7, 0, 16);
+
+ ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
+ if (ret < 0)
+ error("ds4: failed to write master address (%s)",
+ strerror(errno));
+
+ return ret;
+}
+
static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr,
CablePairingType type)
{
if (type == CABLE_PAIRING_SIXAXIS)
return sixaxis_set_master_bdaddr(fd, bdaddr);
+ else if (type == CABLE_PAIRING_DS4)
+ return ds4_set_master_bdaddr(fd, bdaddr);
return -1;
}
@@ -279,7 +349,8 @@ static void device_added(struct udev_device *udevice)
&name,
&source,
&version);
- if (type != CABLE_PAIRING_SIXAXIS)
+ if (type != CABLE_PAIRING_SIXAXIS &&
+ type != CABLE_PAIRING_DS4)
return;
if (bus != BUS_USB)
return;
--
2.14.1

View File

@ -1,290 +0,0 @@
From 9f8fa823a2c8fec78e5a210f5c4a77114652d2ea Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 1 Sep 2017 17:23:38 +0200
Subject: [PATCH 9/9] plugins/sixaxis: Cancel cable pairing if unplugged
Cancel pending authorization requests when the device is unplugged
while a request is pending.
---
plugins/sixaxis.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 123 insertions(+), 15 deletions(-)
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index eb15acb92..5cae52c68 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -51,6 +51,8 @@
#include "profiles/input/sixaxis.h"
struct authentication_closure {
+ guint auth_id;
+ char *sysfs_path;
struct btd_adapter *adapter;
struct btd_device *device;
int fd;
@@ -58,9 +60,29 @@ struct authentication_closure {
CablePairingType type;
};
+struct authentication_destroy_closure {
+ struct authentication_closure *closure;
+ bool remove_device;
+};
+
static struct udev *ctx = NULL;
static struct udev_monitor *monitor = NULL;
static guint watch_id = 0;
+static GHashTable *pending_auths = NULL; /* key = sysfs_path (const str), value = auth_closure */
+
+/* Make sure to unset auth_id if already handled */
+static void auth_closure_destroy(struct authentication_closure *closure,
+ bool remove_device)
+{
+ if (closure->auth_id)
+ btd_cancel_authorization(closure->auth_id);
+
+ if (remove_device)
+ btd_adapter_remove_device(closure->adapter, closure->device);
+ close(closure->fd);
+ g_free(closure->sysfs_path);
+ g_free(closure);
+}
static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
{
@@ -214,41 +236,83 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr,
return -1;
}
+static bool is_auth_pending(struct authentication_closure *closure)
+{
+ GHashTableIter iter;
+ gpointer value;
+
+ g_hash_table_iter_init(&iter, pending_auths);
+ while (g_hash_table_iter_next(&iter, NULL, &value)) {
+ struct authentication_closure *c = value;
+ if (c == closure)
+ return true;
+ }
+ return false;
+}
+
+static gboolean auth_closure_destroy_idle(gpointer user_data)
+{
+ struct authentication_destroy_closure *destroy = user_data;
+
+ auth_closure_destroy(destroy->closure, destroy->remove_device);
+ g_free(destroy);
+
+ return false;
+}
+
static void agent_auth_cb(DBusError *derr,
void *user_data)
{
struct authentication_closure *closure = user_data;
+ struct authentication_destroy_closure *destroy;
char master_addr[18], adapter_addr[18];
bdaddr_t master_bdaddr;
const bdaddr_t *adapter_bdaddr;
+ bool remove_device = true;
+
+ if (!is_auth_pending(closure))
+ return;
+
+ /* Don't try to remove this auth, we're handling it already */
+ closure->auth_id = 0;
if (derr != NULL) {
DBG("Agent replied negatively, removing temporary device");
- goto error;
+ goto out;
}
- btd_device_set_temporary(closure->device, false);
-
if (get_master_bdaddr(closure->fd, &master_bdaddr, closure->type) < 0)
- goto error;
+ goto out;
adapter_bdaddr = btd_adapter_get_address(closure->adapter);
if (bacmp(adapter_bdaddr, &master_bdaddr)) {
if (set_master_bdaddr(closure->fd, adapter_bdaddr, closure->type) < 0)
- goto error;
+ goto out;
}
+ remove_device = false;
+ btd_device_set_temporary(closure->device, false);
+
ba2str(&master_bdaddr, master_addr);
ba2str(adapter_bdaddr, adapter_addr);
DBG("remote %s old_master %s new_master %s",
closure->device_addr, master_addr, adapter_addr);
-error:
- close(closure->fd);
- g_free(closure);
+out:
+ g_hash_table_steal(pending_auths, closure->sysfs_path);
+
+ /* btd_adapter_remove_device() cannot be called in this
+ * callback or it would lead to a double-free in while
+ * trying to cancel the authentication that's being processed,
+ * so clean up in an idle */
+ destroy = g_new0(struct authentication_destroy_closure, 1);
+ destroy->closure = closure;
+ destroy->remove_device = remove_device;
+ g_idle_add(auth_closure_destroy_idle, destroy);
}
static bool setup_device(int fd,
+ const char *sysfs_path,
const char *name,
uint16_t source,
uint16_t vid,
@@ -296,12 +360,15 @@ static bool setup_device(int fd,
}
closure->adapter = adapter;
closure->device = device;
+ closure->sysfs_path = g_strdup(sysfs_path);
closure->fd = fd;
closure->type = type;
memcpy(&closure->device_addr, device_addr, sizeof(device_addr));
adapter_bdaddr = btd_adapter_get_address(adapter);
- btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr,
- HID_UUID, agent_auth_cb, closure);
+ closure->auth_id = btd_request_authorization_cable_configured(adapter_bdaddr, &device_bdaddr,
+ HID_UUID, agent_auth_cb, closure);
+
+ g_hash_table_insert(pending_auths, closure->sysfs_path, closure);
return true;
}
@@ -310,12 +377,14 @@ static CablePairingType get_pairing_type_for_device(struct udev_device *udevice,
uint16_t *bus,
uint16_t *vid,
uint16_t *pid,
+ char **sysfs_path,
char **name,
uint16_t *source,
uint16_t *version)
{
struct udev_device *hid_parent;
const char *hid_id;
+ CablePairingType ret;
hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
"hid", NULL);
@@ -327,14 +396,17 @@ static CablePairingType get_pairing_type_for_device(struct udev_device *udevice,
if (sscanf(hid_id, "%hx:%hx:%hx", bus, vid, pid) != 3)
return -1;
- return get_pairing_type(*vid, *pid, name, source, version);
+ ret = get_pairing_type(*vid, *pid, name, source, version);
+ *sysfs_path = g_strdup(udev_device_get_syspath(udevice));
+
+ return ret;
}
static void device_added(struct udev_device *udevice)
{
struct btd_adapter *adapter;
uint16_t bus, vid, pid, source, version;
- char *name = NULL;
+ char *name = NULL, *sysfs_path = NULL;
CablePairingType type;
int fd;
@@ -346,6 +418,7 @@ static void device_added(struct udev_device *udevice)
&bus,
&vid,
&pid,
+ &sysfs_path,
&name,
&source,
&version);
@@ -355,20 +428,39 @@ static void device_added(struct udev_device *udevice)
if (bus != BUS_USB)
return;
- info("sixaxis: compatible device connected: %s (%04X:%04X)",
- name, vid, pid);
+ info("sixaxis: compatible device connected: %s (%04X:%04X %s)",
+ name, vid, pid, sysfs_path);
fd = open(udev_device_get_devnode(udevice), O_RDWR);
if (fd < 0) {
g_free(name);
+ g_free(sysfs_path);
return;
}
/* Only close the fd if an authentication is not pending */
- if (!setup_device(fd, name, source, vid, pid, version, type, adapter))
+ if (!setup_device(fd, sysfs_path, name, source, vid, pid, version, type, adapter))
close(fd);
g_free(name);
+ g_free(sysfs_path);
+}
+
+static void device_removed(struct udev_device *udevice)
+{
+ struct authentication_closure *closure;
+ const char *sysfs_path;
+
+ sysfs_path = udev_device_get_syspath(udevice);
+ if (!sysfs_path)
+ return;
+
+ closure = g_hash_table_lookup(pending_auths, sysfs_path);
+ if (!closure)
+ return;
+
+ g_hash_table_steal(pending_auths, sysfs_path);
+ auth_closure_destroy(closure, true);
}
static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
@@ -382,6 +474,8 @@ static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
if (!g_strcmp0(udev_device_get_action(udevice), "add"))
device_added(udevice);
+ else if (!g_strcmp0(udev_device_get_action(udevice), "remove"))
+ device_removed(udevice);
udev_device_unref(udevice);
@@ -415,13 +509,27 @@ static int sixaxis_init(void)
watch_id = g_io_add_watch(channel, G_IO_IN, monitor_watch, NULL);
g_io_channel_unref(channel);
+ pending_auths = g_hash_table_new(g_str_hash,
+ g_str_equal);
+
return 0;
}
static void sixaxis_exit(void)
{
+ GHashTableIter iter;
+ gpointer value;
+
DBG("");
+ g_hash_table_iter_init(&iter, pending_auths);
+ while (g_hash_table_iter_next(&iter, NULL, &value)) {
+ struct authentication_closure *closure = value;
+ auth_closure_destroy(closure, true);
+ }
+ g_hash_table_destroy(pending_auths);
+ pending_auths = NULL;
+
g_source_remove(watch_id);
watch_id = 0;
--
2.14.1

View File

@ -1,7 +1,7 @@
Name: bluez
Summary: Bluetooth utilities
Version: 5.47
Release: 7%{?dist}
Version: 5.48
Release: 1%{?dist}
License: GPLv2+
URL: http://www.bluez.org/
@ -16,30 +16,15 @@ Source4: btattach-bcm-service.sh
# https://github.com/hadess/bluez/commits/build-fixes-5.46
Patch0: 0001-build-Enable-BIND_NOW.patch
Patch1: 0002-obexd-Fix-compilation-error-on-F27.patch
Patch2: 0003-tools-csr_usb-Fix-compilation-failure.patch
Patch3: 0004-obex-Work-around-compilation-failure.patch
# https://github.com/hadess/bluez/commits/obex-5.46
Patch4: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch
# https://github.com/hadess/bluez/commits/autopair-5.46
Patch5: 0001-autopair-Don-t-handle-the-iCade.patch
# https://github.com/hadess/bluez/commits/hostname-plugin-5.47
Patch6: 0001-hostname-Fix-BlueZ-5.XX-adapter-name-on-startup.patch
# https://github.com/hadess/bluez/commits/ds4-cable-pairing
Patch101: 0001-plugins-sixaxis-Remove-LEDs-handling.patch
Patch102: 0002-adapter-Add-btd_request_authorization_cable_configur.patch
Patch103: 0003-sixaxis-Ask-user-whether-cable-configuration-should-.patch
Patch104: 0004-plugins-sixaxis-Move-device-discovery-to-shared-head.patch
Patch105: 0005-profiles-input-Use-sixaxis-header-to-simplify-device.patch
Patch106: 0006-profiles-input-Add-DS4-devices-to-the-shared-header.patch
Patch107: 0007-plugins-sixaxis-Rename-sixaxis-specific-functions.patch
Patch108: 0008-plugins-sixaxis-Add-support-for-DualShock-4-PS4-cabl.patch
Patch109: 0009-plugins-sixaxis-Cancel-cable-pairing-if-unplugged.patch
# https://github.com/hadess/bluez/commits/systemd-hardening
Patch120: 0001-build-Always-define-confdir-and-statedir.patch
Patch121: 0002-systemd-Add-PrivateTmp-and-NoNewPrivileges-options.patch
@ -282,6 +267,9 @@ make check
%{_userunitdir}/obex.service
%changelog
* Thu Dec 28 2017 Pete Walter <pwalter@fedoraproject.org> - 5.48-1
- Update to 5.48
* Sun Dec 10 2017 Björn Esser <besser82@fedoraproject.org> - 5.47-7
- Rebuilt for libjson-c.so.3

View File

@ -1 +1 @@
SHA512 (bluez-5.47.tar.xz) = 86fa1baae1593d4824038db8418358b0be624c81fc23ee8f96ec08979d309a2377be3924ab53cc0fcb712aec8e696360e9a9f4de4c12cc31b14de5cf495a11a6
SHA512 (bluez-5.48.tar.xz) = 38cb20b8acee8adaab286a0b042efa770df367e7a69556117961fcc46d9e0a0e2a48059c7df9511bb00fe7fc37e916e34c928df9372b45051fcc57c8965b0bb7