diff --git a/0001-Add-sixaxis-cable-pairing-plugin.patch b/0001-Add-sixaxis-cable-pairing-plugin.patch index 7872b2d..16486a2 100644 --- a/0001-Add-sixaxis-cable-pairing-plugin.patch +++ b/0001-Add-sixaxis-cable-pairing-plugin.patch @@ -1,4 +1,4 @@ -From 61443ce94d503c359a99e7885fe489cfcff380fa Mon Sep 17 00:00:00 2001 +From b9fd541d4ed3320ea9d1796166956a9d03d15e10 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 1 Sep 2009 17:32:48 +0100 Subject: [PATCH] Add sixaxis cable-pairing plugin @@ -15,13 +15,11 @@ address, and added to the database of the current default adapter. plugins/cable.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/adapter.c | 19 +++ src/adapter.h | 3 + - src/manager.c | 5 + - src/manager.h | 1 + - 8 files changed, 434 insertions(+), 2 deletions(-) + 6 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 plugins/cable.c diff --git a/Makefile.am b/Makefile.am -index 2f3051c..145b26d 100644 +index ba9a89d..b5851e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -202,6 +202,11 @@ builtin_sources += health/hdp_main.c health/hdp_types.h \ @@ -45,7 +43,7 @@ index 2f3051c..145b26d 100644 src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \ -Wl,--version-script=$(srcdir)/src/bluetooth.ver -@@ -373,7 +378,7 @@ EXTRA_DIST += doc/manager-api.txt \ +@@ -388,7 +393,7 @@ EXTRA_DIST += doc/manager-api.txt \ AM_YFLAGS = -d @@ -108,7 +106,7 @@ index d77937b..7e6422e 100644 + AM_CONDITIONAL(CABLE, test "${cable_enable}" = "yes" && test "${cable_found}" = "yes") ]) diff --git a/configure.ac b/configure.ac -index 987b7e1..aece18b 100644 +index 084ece5..0ef0225 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,7 @@ AC_PATH_GSTREAMER @@ -508,10 +506,10 @@ index 0000000..e8cff76 +BLUETOOTH_PLUGIN_DEFINE(cable, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, cable_init, cable_exit) diff --git a/src/adapter.c b/src/adapter.c -index 5598d17..86dfccc 100644 +index 156d534..51e3b4c 100644 --- a/src/adapter.c +++ b/src/adapter.c -@@ -1081,6 +1081,25 @@ static struct btd_device *adapter_create_device(DBusConnection *conn, +@@ -1088,6 +1088,25 @@ static struct btd_device *adapter_create_device(DBusConnection *conn, return device; } @@ -538,10 +536,10 @@ index 5598d17..86dfccc 100644 struct btd_device *device, gboolean remove_storage) diff --git a/src/adapter.h b/src/adapter.h -index 13971bf..c85fa66 100644 +index 38ea3ca..55c77aa 100644 --- a/src/adapter.h +++ b/src/adapter.h -@@ -114,6 +114,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr, +@@ -116,6 +116,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr, int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr); void adapter_emit_device_found(struct btd_adapter *adapter, struct remote_dev_info *dev); @@ -551,34 +549,6 @@ index 13971bf..c85fa66 100644 void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode); int adapter_update_local_name(struct btd_adapter *adapter, const char *name); void adapter_service_insert(struct btd_adapter *adapter, void *rec); -diff --git a/src/manager.c b/src/manager.c -index dedec8b..d18d588 100644 ---- a/src/manager.c -+++ b/src/manager.c -@@ -262,6 +262,11 @@ static void manager_set_default_adapter(int id) - DBUS_TYPE_INVALID); - } - -+struct btd_adapter *manager_get_default_adapter(void) -+{ -+ return manager_find_adapter_by_id(default_adapter_id); -+} -+ - static void manager_remove_adapter(struct btd_adapter *adapter) - { - uint16_t dev_id = adapter_get_dev_id(adapter); -diff --git a/src/manager.h b/src/manager.h -index 90d3690..f5f9757 100644 ---- a/src/manager.h -+++ b/src/manager.h -@@ -35,6 +35,7 @@ void manager_cleanup(DBusConnection *conn, const char *path); - const char *manager_get_base_path(void); - struct btd_adapter *manager_find_adapter(const bdaddr_t *sba); - struct btd_adapter *manager_find_adapter_by_id(int id); -+struct btd_adapter *manager_get_default_adapter(void); - void manager_foreach_adapter(adapter_cb func, gpointer user_data); - GSList *manager_get_adapters(void); - struct btd_adapter *btd_manager_register_adapter(int id); -- -1.7.5.1 +1.7.5.4 diff --git a/0001-adaptername-Move-adapter-naming-into-a-plugin.patch b/0001-adaptername-Move-adapter-naming-into-a-plugin.patch deleted file mode 100644 index e6248a5..0000000 --- a/0001-adaptername-Move-adapter-naming-into-a-plugin.patch +++ /dev/null @@ -1,545 +0,0 @@ -From b228f205853a122327a9ce93a75fb88848c02312 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Tue, 10 May 2011 18:02:14 +0100 -Subject: [PATCH] adaptername: Move adapter naming into a plugin - -Moving the adapter naming allows us to use the /etc/machine-info [1] -pretty hostname, as implemented by hostnamed [2] in systemd. - -If /etc/machine-info is not present, the adapter name stored -on disk in /var/lib/bluetooth will be used. If no adapter name -has been set yet, the default from the main.conf will be used. - -We don't currently number the name of hci0 if a pretty name is -available, but we should instead number it if it happens not -to be the default adapter. As we cannot be told when the default -adapter changes, we'll behave this way for now. - -[1]: http://0pointer.de/public/systemd-man/machine-info.html -[2]: http://www.freedesktop.org/wiki/Software/systemd/hostnamed ---- - Makefile.am | 3 + - configure.ac | 4 + - plugins/adaptername.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++ - src/adapter.c | 107 +++---------------- - src/adapter.h | 2 +- - src/manager.c | 5 + - src/manager.h | 1 + - 7 files changed, 319 insertions(+), 92 deletions(-) - create mode 100644 plugins/adaptername.c - -diff --git a/Makefile.am b/Makefile.am -index 175f8c9..2f3051c 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -218,6 +218,9 @@ EXTRA_DIST += plugins/hal.c plugins/formfactor.c - builtin_modules += storage - builtin_sources += plugins/storage.c - -+builtin_modules += adaptername -+builtin_sources += plugins/adaptername.c -+ - if MAEMO6PLUGIN - builtin_modules += maemo6 - builtin_sources += plugins/maemo6.c -diff --git a/configure.ac b/configure.ac -index 111ff01..987b7e1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -35,6 +35,10 @@ AC_FUNC_PPOLL - AC_CHECK_LIB(dl, dlopen, dummy=yes, - AC_MSG_ERROR(dynamic linking loader is required)) - -+AC_CHECK_HEADER([sys/inotify.h], -+ [AC_DEFINE([HAVE_SYS_INOTIFY_H], 1, -+ [Define to 1 if you have .])], -+ [AC_MSG_ERROR(inotify headers are required and missing)]) - AC_PATH_DBUS - AC_PATH_GLIB - AC_PATH_ALSA -diff --git a/plugins/adaptername.c b/plugins/adaptername.c -new file mode 100644 -index 0000000..53c67e9 ---- /dev/null -+++ b/plugins/adaptername.c -@@ -0,0 +1,289 @@ -+/* -+ * -+ * BlueZ - Bluetooth protocol stack for Linux -+ * -+ * Copyright (C) 2004-2010 Marcel Holtmann -+ * -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+#include "plugin.h" -+#include "hcid.h" /* For main_opts */ -+#include "adapter.h" -+#include "manager.h" -+#include "device.h" /* Needed for storage.h */ -+#include "storage.h" -+#include "log.h" -+ -+#include -+#define EVENT_SIZE (sizeof (struct inotify_event)) -+#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) -+ -+#define MACHINE_INFO_DIR "/etc/" -+#define MACHINE_INFO_FILE "machine-info" -+ -+static GIOChannel *inotify = NULL; -+static int watch_fd = -1; -+ -+/* This file is part of systemd's hostnamed functionality: -+ * http://0pointer.de/public/systemd-man/machine-info.html -+ * http://www.freedesktop.org/wiki/Software/systemd/hostnamed -+ */ -+static char *read_pretty_host_name (void) -+{ -+ char *contents, *ret; -+ char **lines; -+ guint i; -+ -+ ret = NULL; -+ -+ if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE, -+ &contents, NULL, NULL) == FALSE) { -+ return NULL; -+ } -+ lines = g_strsplit_set(contents, "\r\n", 0); -+ g_free(contents); -+ -+ if (lines == NULL) -+ return NULL; -+ -+ for (i = 0; lines[i] != NULL; i++) { -+ if (g_str_has_prefix(lines[i], "PRETTY_HOSTNAME=")) { -+ ret = g_strdup(lines[i] + strlen("PRETTY_HOSTNAME=")); -+ break; -+ } -+ } -+ -+ g_strfreev(lines); -+ return ret; -+} -+ -+/* -+ * Device name expansion -+ * %d - device id -+ * %h - hostname -+ */ -+static char *expand_name(char *dst, int size, char *str, int dev_id) -+{ -+ register int sp, np, olen; -+ char *opt, buf[10]; -+ -+ if (!str || !dst) -+ return NULL; -+ -+ sp = np = 0; -+ while (np < size - 1 && str[sp]) { -+ switch (str[sp]) { -+ case '%': -+ opt = NULL; -+ -+ switch (str[sp+1]) { -+ case 'd': -+ sprintf(buf, "%d", dev_id); -+ opt = buf; -+ break; -+ -+ case 'h': -+ opt = main_opts.host_name; -+ break; -+ -+ case '%': -+ dst[np++] = str[sp++]; -+ /* fall through */ -+ default: -+ sp++; -+ continue; -+ } -+ -+ if (opt) { -+ /* substitute */ -+ olen = strlen(opt); -+ if (np + olen < size - 1) -+ memcpy(dst + np, opt, olen); -+ np += olen; -+ } -+ sp += 2; -+ continue; -+ -+ case '\\': -+ sp++; -+ /* fall through */ -+ default: -+ dst[np++] = str[sp++]; -+ break; -+ } -+ } -+ dst[np] = '\0'; -+ return dst; -+} -+ -+static int adaptername_probe(struct btd_adapter *adapter) -+{ -+ int current_id; -+ char name[MAX_NAME_LENGTH + 1]; -+ char *pretty_hostname; -+ bdaddr_t bdaddr; -+ -+ current_id = adapter_get_dev_id(adapter); -+ -+ pretty_hostname = read_pretty_host_name(); -+ if (pretty_hostname != NULL) { -+ int default_adapter; -+ -+ default_adapter = manager_get_default_adapter(); -+ -+ /* If it's the first device, let's assume it will -+ * be the default one, as we're not told when -+ * the default adapter changes */ -+ if (default_adapter < 0) -+ default_adapter = current_id; -+ -+ if (default_adapter != current_id) { -+ char *str; -+ -+ /* +1 because we don't want an adapter called "Foobar's laptop #0" */ -+ str = g_strdup_printf ("%s #%d", pretty_hostname, current_id + 1); -+ DBG("Setting name '%s' for device 'hci%d'", str, current_id); -+ -+ adapter_update_local_name(adapter, str); -+ g_free(str); -+ } else { -+ DBG("Setting name '%s' for device 'hci%d'", pretty_hostname, current_id); -+ adapter_update_local_name(adapter, pretty_hostname); -+ } -+ g_free(pretty_hostname); -+ -+ return 0; -+ } -+ -+ adapter_get_address(adapter, &bdaddr); -+ -+ if (read_local_name(&bdaddr, name) < 0) { -+ expand_name(name, MAX_NAME_LENGTH, main_opts.name, -+ current_id); -+ } -+ DBG("Setting name '%s' for device 'hci%d'", name, current_id); -+ adapter_update_local_name(adapter, name); -+ -+ return 0; -+} -+ -+static gboolean handle_inotify_cb(GIOChannel *channel, -+ GIOCondition condition, gpointer data) -+{ -+ char buf[EVENT_BUF_LEN]; -+ GIOStatus err; -+ gsize len, i; -+ gboolean changed; -+ -+ changed = FALSE; -+ -+ err = g_io_channel_read_chars(channel, buf, EVENT_BUF_LEN, &len, NULL); -+ if (err != G_IO_STATUS_NORMAL) { -+ error("Error reading inotify event: %d\n", err); -+ return FALSE; -+ } -+ -+ i = 0; -+ while (i < len) { -+ struct inotify_event *pevent = (struct inotify_event *) & buf[i]; -+ -+ /* check that it's ours */ -+ if (pevent->len && -+ pevent->name != NULL && -+ strcmp(pevent->name, MACHINE_INFO_FILE) == 0) { -+ changed = TRUE; -+ } -+ i += EVENT_SIZE + pevent->len; -+ } -+ -+ if (changed != FALSE) { -+ DBG(MACHINE_INFO_DIR MACHINE_INFO_FILE -+ " changed, changing names for adapters"); -+ manager_foreach_adapter ((adapter_cb) adaptername_probe, NULL); -+ } -+ -+ return TRUE; -+} -+ -+static void adaptername_remove(struct btd_adapter *adapter) -+{ -+ if (watch_fd >= 0) -+ close (watch_fd); -+ if (inotify != NULL) -+ g_io_channel_shutdown(inotify, FALSE, NULL); -+} -+ -+static struct btd_adapter_driver adaptername_driver = { -+ .name = "adaptername", -+ .probe = adaptername_probe, -+ .remove = adaptername_remove, -+}; -+ -+static int adaptername_init(void) -+{ -+ int ret; -+ -+ ret = btd_register_adapter_driver(&adaptername_driver); -+ -+ if (ret == 0) { -+ int inot_fd; -+ -+ inot_fd = inotify_init(); -+ if (inot_fd < 0) { -+ error("Failed to setup inotify"); -+ return 0; -+ } -+ watch_fd = inotify_add_watch(inot_fd, -+ MACHINE_INFO_DIR, -+ IN_CLOSE_WRITE | IN_DELETE | IN_CREATE); -+ if (watch_fd < 0) { -+ error("Failed to setup watch for '%s'", -+ MACHINE_INFO_DIR); -+ return 0; -+ } -+ -+ inotify = g_io_channel_unix_new(inot_fd); -+ g_io_channel_set_close_on_unref(inotify, TRUE); -+ g_io_channel_set_encoding (inotify, NULL, NULL); -+ g_io_channel_set_flags (inotify, G_IO_FLAG_NONBLOCK, NULL); -+ g_io_add_watch(inotify, G_IO_IN, handle_inotify_cb, NULL); -+ -+ return 0; -+ } -+ -+ return ret; -+} -+ -+static void adaptername_exit(void) -+{ -+ btd_unregister_adapter_driver(&adaptername_driver); -+} -+ -+BLUETOOTH_PLUGIN_DEFINE(adaptername, VERSION, -+ BLUETOOTH_PLUGIN_PRIORITY_LOW, adaptername_init, adaptername_exit) -diff --git a/src/adapter.c b/src/adapter.c -index c30febc..5598d17 100644 ---- a/src/adapter.c -+++ b/src/adapter.c -@@ -182,64 +182,6 @@ static void dev_info_free(struct remote_dev_info *dev) - g_free(dev); - } - --/* -- * Device name expansion -- * %d - device id -- */ --static char *expand_name(char *dst, int size, char *str, int dev_id) --{ -- register int sp, np, olen; -- char *opt, buf[10]; -- -- if (!str || !dst) -- return NULL; -- -- sp = np = 0; -- while (np < size - 1 && str[sp]) { -- switch (str[sp]) { -- case '%': -- opt = NULL; -- -- switch (str[sp+1]) { -- case 'd': -- sprintf(buf, "%d", dev_id); -- opt = buf; -- break; -- -- case 'h': -- opt = main_opts.host_name; -- break; -- -- case '%': -- dst[np++] = str[sp++]; -- /* fall through */ -- default: -- sp++; -- continue; -- } -- -- if (opt) { -- /* substitute */ -- olen = strlen(opt); -- if (np + olen < size - 1) -- memcpy(dst + np, opt, olen); -- np += olen; -- } -- sp += 2; -- continue; -- -- case '\\': -- sp++; -- /* fall through */ -- default: -- dst[np++] = str[sp++]; -- break; -- } -- } -- dst[np] = '\0'; -- return dst; --} -- - int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major, - uint8_t minor) - { -@@ -912,10 +854,10 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint32_t new_class) - DBUS_TYPE_UINT32, &new_class); - } - --void adapter_update_local_name(struct btd_adapter *adapter, const char *name) -+int adapter_update_local_name(struct btd_adapter *adapter, const char *name) - { - if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) -- return; -+ return 0; - - strncpy(adapter->name, name, MAX_NAME_LENGTH); - -@@ -934,38 +876,29 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name) - DBUS_TYPE_STRING, &name_ptr); - } - -+ if (adapter->up) { -+ int err = adapter_ops->set_name(adapter->dev_id, name); -+ if (err < 0) -+ return -err; -+ -+ adapter->name_stored = TRUE; -+ } -+ - adapter->name_stored = FALSE; -+ -+ return 0; - } - - static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg, - const char *name, void *data) - { - struct btd_adapter *adapter = data; -- char *name_ptr = adapter->name; -- -- if (!g_utf8_validate(name, -1, NULL)) { -- error("Name change failed: supplied name isn't valid UTF-8"); -- return btd_error_invalid_args(msg); -- } -- -- if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) -- goto done; -- -- strncpy(adapter->name, name, MAX_NAME_LENGTH); -- write_local_name(&adapter->bdaddr, name); -- emit_property_changed(connection, adapter->path, -- ADAPTER_INTERFACE, "Name", -- DBUS_TYPE_STRING, &name_ptr); -- -- if (adapter->up) { -- int err = adapter_ops->set_name(adapter->dev_id, name); -- if (err < 0) -- return btd_error_failed(msg, strerror(-err)); -+ int err; - -- adapter->name_stored = TRUE; -- } -+ err = adapter_update_local_name (adapter, name); -+ if (err < 0) -+ return btd_error_failed(msg, strerror(err)); - --done: - return dbus_message_new_method_return(msg); - } - -@@ -2577,14 +2510,6 @@ gboolean adapter_init(struct btd_adapter *adapter) - return FALSE; - } - -- if (read_local_name(&adapter->bdaddr, adapter->name) < 0) -- expand_name(adapter->name, MAX_NAME_LENGTH, main_opts.name, -- adapter->dev_id); -- -- if (main_opts.attrib_server) -- attrib_gap_set(GATT_CHARAC_DEVICE_NAME, -- (const uint8_t *) adapter->name, strlen(adapter->name)); -- - sdp_init_services_list(&adapter->bdaddr); - load_drivers(adapter); - clear_blocked(adapter); -diff --git a/src/adapter.h b/src/adapter.h -index 3526849..13971bf 100644 ---- a/src/adapter.h -+++ b/src/adapter.h -@@ -115,7 +115,7 @@ int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr); - void adapter_emit_device_found(struct btd_adapter *adapter, - struct remote_dev_info *dev); - void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode); --void adapter_update_local_name(struct btd_adapter *adapter, const char *name); -+int adapter_update_local_name(struct btd_adapter *adapter, const char *name); - void adapter_service_insert(struct btd_adapter *adapter, void *rec); - void adapter_service_remove(struct btd_adapter *adapter, void *rec); - void btd_adapter_class_changed(struct btd_adapter *adapter, -diff --git a/src/manager.c b/src/manager.c -index e805e0c..dedec8b 100644 ---- a/src/manager.c -+++ b/src/manager.c -@@ -288,6 +288,11 @@ static void manager_remove_adapter(struct btd_adapter *adapter) - btd_start_exit_timer(); - } - -+int manager_get_default_adapter (void) -+{ -+ return default_adapter_id; -+} -+ - void manager_cleanup(DBusConnection *conn, const char *path) - { - g_slist_foreach(adapters, (GFunc) manager_remove_adapter, NULL); -diff --git a/src/manager.h b/src/manager.h -index 05c38b3..90d3690 100644 ---- a/src/manager.h -+++ b/src/manager.h -@@ -41,3 +41,4 @@ struct btd_adapter *btd_manager_register_adapter(int id); - int btd_manager_unregister_adapter(int id); - void manager_add_adapter(const char *path); - void btd_manager_set_did(uint16_t vendor, uint16_t product, uint16_t version); -+int manager_get_default_adapter (void); --- -1.7.5.1 - diff --git a/bluez.spec b/bluez.spec index ac9bb04..c1ef2f0 100644 --- a/bluez.spec +++ b/bluez.spec @@ -1,7 +1,7 @@ Summary: Bluetooth utilities Name: bluez Version: 4.94 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv2+ Group: Applications/System Source: http://www.kernel.org/pub/linux/bluetooth/%{name}-%{version}.tar.gz @@ -13,7 +13,7 @@ Source7: rfcomm.init Source8: bluez-uinput.modules # http://thread.gmane.org/gmane.linux.bluez.kernel/13255 -Patch1: 0001-adaptername-Move-adapter-naming-into-a-plugin.patch +Patch1: pretty-hostname-support.patch # https://bugzilla.redhat.com/show_bug.cgi?id=498756 Patch4: bluez-socket-mobile-cf-connection-kit.patch # http://thread.gmane.org/gmane.linux.bluez.kernel/2396 @@ -236,6 +236,7 @@ fi %{_bindir}/l2ping %{_bindir}/rfcomm %{_bindir}/sdptool +%{_bindir}/gattool %{_sbindir}/* %{_mandir}/man1/ciptool.1.gz %{_mandir}/man1/dfutool.1.gz @@ -295,6 +296,10 @@ fi %{_mandir}/man1/pand.1.gz %changelog +* Thu Jun 23 2011 Bastien Nocera 4.94-3 +- Update patches to apply correctly +- First compilable version with hostnamed support + * Mon Jun 20 2011 Lennart Poettering - 4.94-2 - Enable bluetoothd by default - Follow-up on https://bugzilla.redhat.com/show_bug.cgi?id=694519 also fixing upgrades diff --git a/pretty-hostname-support.patch b/pretty-hostname-support.patch new file mode 100644 index 0000000..b04139e --- /dev/null +++ b/pretty-hostname-support.patch @@ -0,0 +1,714 @@ +From fedee1259e50a5312720adc895bc2fd0270395aa Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Thu, 9 Jun 2011 14:41:56 +0100 +Subject: [PATCH 1/3] Simplify "SetName" D-Bus call + +By merging most of the functionality into adapter_update_local_name() +This also allows us to drop the adapter->name_stored struct member +as in any calls to adapter_update_local_name(), we would want to +write out the adapter name. +--- + src/adapter.c | 61 ++++++++++++++++++++++++-------------------------------- + src/adapter.h | 2 +- + 2 files changed, 27 insertions(+), 36 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index 2650b56..f8c0370 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -146,8 +146,6 @@ struct btd_adapter { + + GSList *powered_callbacks; + +- gboolean name_stored; +- + GSList *loaded_drivers; + }; + +@@ -914,10 +912,17 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint32_t new_class) + DBUS_TYPE_UINT32, &new_class); + } + +-void adapter_update_local_name(struct btd_adapter *adapter, const char *name) ++int adapter_update_local_name(struct btd_adapter *adapter, const char *name) + { ++ char *name_ptr; ++ + if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) +- return; ++ return 0; ++ ++ if (!g_utf8_validate(name, -1, NULL)) { ++ error("Name change failed: supplied name isn't valid UTF-8"); ++ return -EINVAL; ++ } + + strncpy(adapter->name, name, MAX_NAME_LENGTH); + +@@ -925,49 +930,36 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name) + attrib_gap_set(GATT_CHARAC_DEVICE_NAME, + (const uint8_t *) adapter->name, strlen(adapter->name)); + +- if (!adapter->name_stored) { +- char *name_ptr = adapter->name; ++ name_ptr = adapter->name; + +- write_local_name(&adapter->bdaddr, adapter->name); ++ write_local_name(&adapter->bdaddr, adapter->name); + +- if (connection) +- emit_property_changed(connection, adapter->path, +- ADAPTER_INTERFACE, "Name", +- DBUS_TYPE_STRING, &name_ptr); ++ if (connection) ++ emit_property_changed(connection, adapter->path, ++ ADAPTER_INTERFACE, "Name", ++ DBUS_TYPE_STRING, &name_ptr); ++ ++ if (adapter->up) { ++ int err = adapter_ops->set_name(adapter->dev_id, name); ++ if (err < 0) ++ return err; + } + +- adapter->name_stored = FALSE; ++ return 0; + } + + static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg, + const char *name, void *data) + { + struct btd_adapter *adapter = data; +- char *name_ptr = adapter->name; ++ int ret; + +- if (!g_utf8_validate(name, -1, NULL)) { +- error("Name change failed: supplied name isn't valid UTF-8"); ++ ret = adapter_update_local_name(adapter, name); ++ if (ret == -EINVAL) + return btd_error_invalid_args(msg); +- } +- +- if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) +- goto done; +- +- strncpy(adapter->name, name, MAX_NAME_LENGTH); +- write_local_name(&adapter->bdaddr, name); +- emit_property_changed(connection, adapter->path, +- ADAPTER_INTERFACE, "Name", +- DBUS_TYPE_STRING, &name_ptr); ++ else if (ret < 0) ++ return btd_error_failed(msg, strerror(-ret)); + +- if (adapter->up) { +- int err = adapter_ops->set_name(adapter->dev_id, name); +- if (err < 0) +- return btd_error_failed(msg, strerror(-err)); +- +- adapter->name_stored = TRUE; +- } +- +-done: + return dbus_message_new_method_return(msg); + } + +@@ -2496,7 +2488,6 @@ int btd_adapter_stop(struct btd_adapter *adapter) + adapter->mode = MODE_OFF; + adapter->state = STATE_IDLE; + adapter->off_requested = FALSE; +- adapter->name_stored = FALSE; + + call_adapter_powered_callbacks(adapter, FALSE); + +diff --git a/src/adapter.h b/src/adapter.h +index 610331f..9516a99 100644 +--- a/src/adapter.h ++++ b/src/adapter.h +@@ -115,7 +115,7 @@ int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr); + void adapter_emit_device_found(struct btd_adapter *adapter, + struct remote_dev_info *dev); + void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode); +-void adapter_update_local_name(struct btd_adapter *adapter, const char *name); ++int adapter_update_local_name(struct btd_adapter *adapter, const char *name); + void adapter_service_insert(struct btd_adapter *adapter, void *rec); + void adapter_service_remove(struct btd_adapter *adapter, void *rec); + void btd_adapter_class_changed(struct btd_adapter *adapter, +-- +1.7.5.4 + + +From c43704f16387fc645260bc68cd9a844dbfa1624c Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jun 2011 11:56:53 +0100 +Subject: [PATCH 2/3] Add ability to block name changes + +--- + src/adapter.c | 12 ++++++++++++ + src/adapter.h | 2 ++ + 2 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index f8c0370..5420acd 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -111,6 +111,7 @@ struct btd_adapter { + bdaddr_t bdaddr; /* adapter Bluetooth Address */ + uint32_t dev_class; /* Class of Device */ + char name[MAX_NAME_LENGTH + 1]; /* adapter name */ ++ gboolean allow_name_changes; /* whether the adapter name can be changed */ + guint discov_timeout_id; /* discoverable timeout id */ + guint stop_discov_id; /* stop inquiry/scanning id */ + uint32_t discov_timeout; /* discoverable time(sec) */ +@@ -916,6 +917,9 @@ int adapter_update_local_name(struct btd_adapter *adapter, const char *name) + { + char *name_ptr; + ++ if (adapter->allow_name_changes == FALSE) ++ return -EPERM; ++ + if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) + return 0; + +@@ -2563,6 +2567,8 @@ gboolean adapter_init(struct btd_adapter *adapter) + * start off as powered */ + adapter->up = TRUE; + ++ adapter->allow_name_changes = TRUE; ++ + adapter_ops->read_bdaddr(adapter->dev_id, &adapter->bdaddr); + + if (bacmp(&adapter->bdaddr, BDADDR_ANY) == 0) { +@@ -2663,6 +2669,12 @@ void adapter_get_address(struct btd_adapter *adapter, bdaddr_t *bdaddr) + bacpy(bdaddr, &adapter->bdaddr); + } + ++void adapter_set_allow_name_changes(struct btd_adapter *adapter, ++ gboolean allow_name_changes) ++{ ++ adapter->allow_name_changes = allow_name_changes; ++} ++ + static inline void suspend_discovery(struct btd_adapter *adapter) + { + if (adapter->state != STATE_SUSPENDED) +diff --git a/src/adapter.h b/src/adapter.h +index 9516a99..38ea3ca 100644 +--- a/src/adapter.h ++++ b/src/adapter.h +@@ -100,6 +100,8 @@ int adapter_resolve_names(struct btd_adapter *adapter); + struct btd_adapter *adapter_create(DBusConnection *conn, int id); + gboolean adapter_init(struct btd_adapter *adapter); + void adapter_remove(struct btd_adapter *adapter); ++void adapter_set_allow_name_changes(struct btd_adapter *adapter, ++ gboolean allow_name_changes); + uint16_t adapter_get_dev_id(struct btd_adapter *adapter); + const gchar *adapter_get_path(struct btd_adapter *adapter); + void adapter_get_address(struct btd_adapter *adapter, bdaddr_t *bdaddr); +-- +1.7.5.4 + + +From 4b8e0372aaaa35219814649b1fb91c222c4c5bab Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jun 2011 12:03:22 +0100 +Subject: [PATCH 3/3] Add adaptername plugin + +Replacing the name setting code in src/adapter.c. + +Moving the adapter naming allows us to use the /etc/machine-info [1] +pretty hostname, as implemented by hostnamed [2] in systemd. + +If /etc/machine-info is not present, the adapter name stored +on disk in /var/lib/bluetooth will be used. If no adapter name +has been set yet, the default from the main.conf will be used. + +We don't currently number the name of hci0 if a pretty name is +available, but we should instead number it if it happens not +to be the default adapter. As we cannot be told when the default +adapter changes, we'll behave this way for now. + +Note that when an adapter name is set automatically from +the pretty hostname, changing it through the D-Bus interface +will fail. + +[1]: http://0pointer.de/public/systemd-man/machine-info.html +[2]: http://www.freedesktop.org/wiki/Software/systemd/hostnamed +--- + Makefile.am | 3 + + configure.ac | 4 + + plugins/adaptername.c | 306 +++++++++++++++++++++++++++++++++++++++++++++++++ + src/adapter.c | 66 ----------- + 4 files changed, 313 insertions(+), 66 deletions(-) + create mode 100644 plugins/adaptername.c + +diff --git a/Makefile.am b/Makefile.am +index c2a6976..ba9a89d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -218,6 +218,9 @@ EXTRA_DIST += plugins/hal.c plugins/formfactor.c + builtin_modules += storage + builtin_sources += plugins/storage.c + ++builtin_modules += adaptername ++builtin_sources += plugins/adaptername.c ++ + if MAEMO6PLUGIN + builtin_modules += maemo6 + builtin_sources += plugins/maemo6.c +diff --git a/configure.ac b/configure.ac +index 07b9e55..084ece5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -35,6 +35,10 @@ AC_FUNC_PPOLL + AC_CHECK_LIB(dl, dlopen, dummy=yes, + AC_MSG_ERROR(dynamic linking loader is required)) + ++AC_CHECK_HEADER([sys/inotify.h], ++ [AC_DEFINE([HAVE_SYS_INOTIFY_H], 1, ++ [Define to 1 if you have .])], ++ [AC_MSG_ERROR(inotify headers are required and missing)]) + AC_PATH_DBUS + AC_PATH_GLIB + AC_PATH_ALSA +diff --git a/plugins/adaptername.c b/plugins/adaptername.c +new file mode 100644 +index 0000000..af4dac8 +--- /dev/null ++++ b/plugins/adaptername.c +@@ -0,0 +1,306 @@ ++/* ++ * ++ * BlueZ - Bluetooth protocol stack for Linux ++ * ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * ++ * 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 ++ * ++ * Author: Bastien Nocera ++ * ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "plugin.h" ++#include "hcid.h" /* For main_opts */ ++#include "adapter.h" ++#include "manager.h" ++#include "device.h" /* Needed for storage.h */ ++#include "storage.h" ++#include "log.h" ++ ++#include ++#define EVENT_SIZE (sizeof (struct inotify_event)) ++#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) ++ ++#define MACHINE_INFO_DIR "/etc/" ++#define MACHINE_INFO_FILE "machine-info" ++ ++static GIOChannel *inotify = NULL; ++static int watch_fd = -1; ++ ++/* This file is part of systemd's hostnamed functionality: ++ * http://0pointer.de/public/systemd-man/machine-info.html ++ * http://www.freedesktop.org/wiki/Software/systemd/hostnamed ++ */ ++static char *read_pretty_host_name(void) ++{ ++ char *contents, *ret; ++ char **lines; ++ guint i; ++ ++ if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE, ++ &contents, NULL, NULL) == FALSE) { ++ return NULL; ++ } ++ lines = g_strsplit_set(contents, "\r\n", 0); ++ g_free(contents); ++ ++ if (lines == NULL) ++ return NULL; ++ ++ ret = NULL; ++ for (i = 0; lines[i] != NULL; i++) { ++ if (g_str_has_prefix(lines[i], "PRETTY_HOSTNAME=")) { ++ ret = g_strdup(lines[i] + strlen("PRETTY_HOSTNAME=")); ++ break; ++ } ++ } ++ ++ g_strfreev(lines); ++ ++ return ret; ++} ++ ++/* ++ * Device name expansion ++ * %d - device id ++ * %h - hostname ++ */ ++static char *expand_name(char *dst, int size, char *str, int dev_id) ++{ ++ register int sp, np, olen; ++ char *opt, buf[10]; ++ ++ if (!str || !dst) ++ return NULL; ++ ++ sp = np = 0; ++ while (np < size - 1 && str[sp]) { ++ switch (str[sp]) { ++ case '%': ++ opt = NULL; ++ ++ switch (str[sp+1]) { ++ case 'd': ++ sprintf(buf, "%d", dev_id); ++ opt = buf; ++ break; ++ ++ case 'h': ++ opt = main_opts.host_name; ++ break; ++ ++ case '%': ++ dst[np++] = str[sp++]; ++ /* fall through */ ++ default: ++ sp++; ++ continue; ++ } ++ ++ if (opt) { ++ /* substitute */ ++ olen = strlen(opt); ++ if (np + olen < size - 1) ++ memcpy(dst + np, opt, olen); ++ np += olen; ++ } ++ sp += 2; ++ continue; ++ ++ case '\\': ++ sp++; ++ /* fall through */ ++ default: ++ dst[np++] = str[sp++]; ++ break; ++ } ++ } ++ dst[np] = '\0'; ++ return dst; ++} ++ ++static int ++get_default_adapter_id(void) ++{ ++ struct btd_adapter *default_adapter; ++ default_adapter = manager_get_default_adapter(); ++ if (default_adapter == NULL) ++ return -1; ++ return adapter_get_dev_id(default_adapter); ++} ++ ++static int adaptername_probe(struct btd_adapter *adapter) ++{ ++ int current_id; ++ char name[MAX_NAME_LENGTH + 1]; ++ char *pretty_hostname; ++ bdaddr_t bdaddr; ++ ++ current_id = adapter_get_dev_id(adapter); ++ ++ pretty_hostname = read_pretty_host_name(); ++ if (pretty_hostname != NULL) { ++ int default_adapter; ++ ++ default_adapter = get_default_adapter_id(); ++ ++ /* Allow us to change the name */ ++ adapter_set_allow_name_changes(adapter, TRUE); ++ ++ /* If it's the first device, let's assume it will ++ * be the default one, as we're not told when ++ * the default adapter changes */ ++ if (default_adapter < 0) ++ default_adapter = current_id; ++ ++ if (default_adapter != current_id) { ++ char *str; ++ ++ /* +1 because we don't want an adapter called "Foobar's laptop #0" */ ++ str = g_strdup_printf("%s #%d", pretty_hostname, current_id + 1); ++ DBG("Setting name '%s' for device 'hci%d'", str, current_id); ++ ++ adapter_update_local_name(adapter, str); ++ g_free(str); ++ } else { ++ DBG("Setting name '%s' for device 'hci%d'", pretty_hostname, current_id); ++ adapter_update_local_name(adapter, pretty_hostname); ++ } ++ g_free(pretty_hostname); ++ ++ /* And disable the name change now */ ++ adapter_set_allow_name_changes(adapter, FALSE); ++ ++ return 0; ++ } ++ ++ adapter_set_allow_name_changes(adapter, TRUE); ++ adapter_get_address(adapter, &bdaddr); ++ ++ if (read_local_name(&bdaddr, name) < 0) ++ expand_name(name, MAX_NAME_LENGTH, main_opts.name, ++ current_id); ++ DBG("Setting name '%s' for device 'hci%d'", name, current_id); ++ adapter_update_local_name(adapter, name); ++ ++ return 0; ++} ++ ++static gboolean handle_inotify_cb(GIOChannel *channel, ++ GIOCondition condition, gpointer data) ++{ ++ char buf[EVENT_BUF_LEN]; ++ GIOStatus err; ++ gsize len, i; ++ gboolean changed; ++ ++ changed = FALSE; ++ ++ err = g_io_channel_read_chars(channel, buf, EVENT_BUF_LEN, &len, NULL); ++ if (err != G_IO_STATUS_NORMAL) { ++ error("Error reading inotify event: %d\n", err); ++ return FALSE; ++ } ++ ++ i = 0; ++ while (i < len) { ++ struct inotify_event *pevent = (struct inotify_event *) &buf[i]; ++ ++ /* check that it's ours */ ++ if (pevent->len && ++ pevent->name != NULL && ++ strcmp(pevent->name, MACHINE_INFO_FILE) == 0) { ++ changed = TRUE; ++ } ++ i += EVENT_SIZE + pevent->len; ++ } ++ ++ if (changed != FALSE) { ++ DBG(MACHINE_INFO_DIR MACHINE_INFO_FILE ++ " changed, changing names for adapters"); ++ manager_foreach_adapter((adapter_cb) adaptername_probe, NULL); ++ } ++ ++ return TRUE; ++} ++ ++static void adaptername_remove(struct btd_adapter *adapter) ++{ ++ if (watch_fd >= 0) ++ close(watch_fd); ++ if (inotify != NULL) ++ g_io_channel_shutdown(inotify, FALSE, NULL); ++} ++ ++static struct btd_adapter_driver adaptername_driver = { ++ .name = "adaptername", ++ .probe = adaptername_probe, ++ .remove = adaptername_remove, ++}; ++ ++static int adaptername_init(void) ++{ ++ int ret; ++ int inot_fd; ++ ++ ret = btd_register_adapter_driver(&adaptername_driver); ++ ++ if (ret != 0) ++ return ret; ++ ++ inot_fd = inotify_init(); ++ if (inot_fd < 0) { ++ error("Failed to setup inotify"); ++ return 0; ++ } ++ watch_fd = inotify_add_watch(inot_fd, ++ MACHINE_INFO_DIR, ++ IN_CLOSE_WRITE | IN_DELETE | IN_CREATE | ++ IN_MOVED_FROM | IN_MOVED_TO); ++ if (watch_fd < 0) { ++ error("Failed to setup watch for '%s'", ++ MACHINE_INFO_DIR); ++ return 0; ++ } ++ ++ inotify = g_io_channel_unix_new(inot_fd); ++ g_io_channel_set_close_on_unref(inotify, TRUE); ++ g_io_channel_set_encoding(inotify, NULL, NULL); ++ g_io_channel_set_flags(inotify, G_IO_FLAG_NONBLOCK, NULL); ++ g_io_add_watch(inotify, G_IO_IN, handle_inotify_cb, NULL); ++ ++ return 0; ++} ++ ++static void adaptername_exit(void) ++{ ++ btd_unregister_adapter_driver(&adaptername_driver); ++} ++ ++BLUETOOTH_PLUGIN_DEFINE(adaptername, VERSION, ++ BLUETOOTH_PLUGIN_PRIORITY_LOW, adaptername_init, adaptername_exit) +diff --git a/src/adapter.c b/src/adapter.c +index 5420acd..156d534 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -183,64 +183,6 @@ static void dev_info_free(struct remote_dev_info *dev) + g_free(dev); + } + +-/* +- * Device name expansion +- * %d - device id +- */ +-static char *expand_name(char *dst, int size, char *str, int dev_id) +-{ +- register int sp, np, olen; +- char *opt, buf[10]; +- +- if (!str || !dst) +- return NULL; +- +- sp = np = 0; +- while (np < size - 1 && str[sp]) { +- switch (str[sp]) { +- case '%': +- opt = NULL; +- +- switch (str[sp+1]) { +- case 'd': +- sprintf(buf, "%d", dev_id); +- opt = buf; +- break; +- +- case 'h': +- opt = main_opts.host_name; +- break; +- +- case '%': +- dst[np++] = str[sp++]; +- /* fall through */ +- default: +- sp++; +- continue; +- } +- +- if (opt) { +- /* substitute */ +- olen = strlen(opt); +- if (np + olen < size - 1) +- memcpy(dst + np, opt, olen); +- np += olen; +- } +- sp += 2; +- continue; +- +- case '\\': +- sp++; +- /* fall through */ +- default: +- dst[np++] = str[sp++]; +- break; +- } +- } +- dst[np] = '\0'; +- return dst; +-} +- + int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major, + uint8_t minor) + { +@@ -2576,14 +2518,6 @@ gboolean adapter_init(struct btd_adapter *adapter) + return FALSE; + } + +- if (read_local_name(&adapter->bdaddr, adapter->name) < 0) +- expand_name(adapter->name, MAX_NAME_LENGTH, main_opts.name, +- adapter->dev_id); +- +- if (main_opts.attrib_server) +- attrib_gap_set(GATT_CHARAC_DEVICE_NAME, +- (const uint8_t *) adapter->name, strlen(adapter->name)); +- + sdp_init_services_list(&adapter->bdaddr); + load_drivers(adapter); + clear_blocked(adapter); +-- +1.7.5.4 + +From e93fae6f51494e36f011a4a22efab7769fd0b8fb Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 8 Jun 2011 15:09:16 +0200 +Subject: [PATCH] Re-add manager_get_default_adapter() + +This will be useful for upcoming plugins like the sixaxis one or the +adaptername one. +--- + src/manager.c | 5 +++++ + src/manager.h | 1 + + 2 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/src/manager.c b/src/manager.c +index e805e0c..254ace4 100644 +--- a/src/manager.c ++++ b/src/manager.c +@@ -262,6 +262,11 @@ static void manager_set_default_adapter(int id) + DBUS_TYPE_INVALID); + } + ++struct btd_adapter *manager_get_default_adapter(void) ++{ ++ return manager_find_adapter_by_id(default_adapter_id); ++} ++ + static void manager_remove_adapter(struct btd_adapter *adapter) + { + uint16_t dev_id = adapter_get_dev_id(adapter); +diff --git a/src/manager.h b/src/manager.h +index 05c38b3..4f92d2f 100644 +--- a/src/manager.h ++++ b/src/manager.h +@@ -35,6 +35,7 @@ void manager_cleanup(DBusConnection *conn, const char *path); + const char *manager_get_base_path(void); + struct btd_adapter *manager_find_adapter(const bdaddr_t *sba); + struct btd_adapter *manager_find_adapter_by_id(int id); ++struct btd_adapter *manager_get_default_adapter(void); + void manager_foreach_adapter(adapter_cb func, gpointer user_data); + GSList *manager_get_adapters(void); + struct btd_adapter *btd_manager_register_adapter(int id); +-- +1.7.5.4 +