All of lore.kernel.org
 help / color / mirror / Atom feed
* Another pass at adapter naming
@ 2011-05-26 14:11 Bastien Nocera
  2011-05-26 14:50 ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-05-26 14:11 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]

As discussed on IRC,

inotify is now required, and we force hci0 (or the first device) to be
named after the pretty hostname.

Note that the GATT call isn't removed, it's now done in
adapter_update_local_name().

Cheers

[-- Attachment #2: 0001-adaptername-Move-adapter-naming-into-a-plugin.patch --]
[-- Type: text/x-patch, Size: 14256 bytes --]

>From b228f205853a122327a9ce93a75fb88848c02312 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
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 <sys/inotify.h>.])],
+			   [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 <marcel@holtmann.org>
+ *
+ *
+ *  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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#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 <sys/inotify.h>
+#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


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 14:11 Another pass at adapter naming Bastien Nocera
@ 2011-05-26 14:50 ` Bastien Nocera
  2011-05-26 16:00   ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-05-26 14:50 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 395 bytes --]

On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
> As discussed on IRC,
> 
> inotify is now required, and we force hci0 (or the first device) to be
> named after the pretty hostname.
> 
> Note that the GATT call isn't removed, it's now done in
> adapter_update_local_name().

As discussed again, removed the default adapter special casing, and
we'll just call hci0 with the pretty name.

[-- Attachment #2: 0001-adaptername-Move-adapter-naming-into-a-plugin.patch --]
[-- Type: text/x-patch, Size: 12930 bytes --]

>From 2ddb830390100b6614be228331635d2e3fc9b9d8 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
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.

If a pretty name is available, hci0 will be using this name,
and further adapters will have a number appended.

[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 |  279 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c         |  107 +++----------------
 src/adapter.h         |    2 +-
 5 files changed, 303 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 <sys/inotify.h>.])],
+			   [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..56a74c9
--- /dev/null
+++ b/plugins/adaptername.c
@@ -0,0 +1,279 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#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 <sys/inotify.h>
+#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) {
+		if (current_id != 0) {
+			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,
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 14:50 ` Bastien Nocera
@ 2011-05-26 16:00   ` Luiz Augusto von Dentz
  2011-05-26 16:12     ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Luiz Augusto von Dentz @ 2011-05-26 16:00 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: BlueZ development

Hi Bastien,

On Thu, May 26, 2011 at 5:50 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
>> As discussed on IRC,
>>
>> inotify is now required, and we force hci0 (or the first device) to be
>> named after the pretty hostname.
>>
>> Note that the GATT call isn't removed, it's now done in
>> adapter_update_local_name().
>
> As discussed again, removed the default adapter special casing, and
> we'll just call hci0 with the pretty name.

Does this means that the user cannot change permanently its adapter
name when pretty hostname is available? In that case I would suggest
having the stored name before pretty name otherwise if bluetoothd is
restarted the adapter name will be reset to pretty hostname again.


-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 16:00   ` Luiz Augusto von Dentz
@ 2011-05-26 16:12     ` Bastien Nocera
  2011-05-26 16:46       ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-05-26 16:12 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: BlueZ development

On Thu, 2011-05-26 at 19:00 +0300, Luiz Augusto von Dentz wrote:
> Hi Bastien,
> 
> On Thu, May 26, 2011 at 5:50 PM, Bastien Nocera <hadess@hadess.net> wrote:
> > On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
> >> As discussed on IRC,
> >>
> >> inotify is now required, and we force hci0 (or the first device) to be
> >> named after the pretty hostname.
> >>
> >> Note that the GATT call isn't removed, it's now done in
> >> adapter_update_local_name().
> >
> > As discussed again, removed the default adapter special casing, and
> > we'll just call hci0 with the pretty name.
> 
> Does this means that the user cannot change permanently its adapter
> name when pretty hostname is available? In that case I would suggest
> having the stored name before pretty name otherwise if bluetoothd is
> restarted the adapter name will be reset to pretty hostname again.

I don't see that as a problem. In which cases exactly would you want the
device name to be different from the pretty hostname?



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 16:12     ` Bastien Nocera
@ 2011-05-26 16:46       ` Luiz Augusto von Dentz
  2011-05-26 16:56         ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Luiz Augusto von Dentz @ 2011-05-26 16:46 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: BlueZ development

Hi Bastien,

On Thu, May 26, 2011 at 7:12 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Thu, 2011-05-26 at 19:00 +0300, Luiz Augusto von Dentz wrote:
>> Hi Bastien,
>>
>> On Thu, May 26, 2011 at 5:50 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> > On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
>> >> As discussed on IRC,
>> >>
>> >> inotify is now required, and we force hci0 (or the first device) to be
>> >> named after the pretty hostname.
>> >>
>> >> Note that the GATT call isn't removed, it's now done in
>> >> adapter_update_local_name().
>> >
>> > As discussed again, removed the default adapter special casing, and
>> > we'll just call hci0 with the pretty name.
>>
>> Does this means that the user cannot change permanently its adapter
>> name when pretty hostname is available? In that case I would suggest
>> having the stored name before pretty name otherwise if bluetoothd is
>> restarted the adapter name will be reset to pretty hostname again.
>
> I don't see that as a problem. In which cases exactly would you want the
> device name to be different from the pretty hostname?

Well that change the current behavior which is to restore the last
name set, so if I set the name to FooBar1 and restart the device I
want FooBar1 back after boot not pretty hostname, otherwise we can
just make Name property read-only.

In other words, if we want to be consistent there is only 2 options:

1. Allow the user application to change the adapter name, the order
then should be stored name > pretty hostname > name configured on
main.conf.

2. Do no allow user to change adapter name directly if pretty hostname
exists, Name property should be made read-only (breaks API?), user can
only change the adapter name via pretty hostname.

-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 16:46       ` Luiz Augusto von Dentz
@ 2011-05-26 16:56         ` Bastien Nocera
  2011-05-30 12:05           ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-05-26 16:56 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: BlueZ development

On Thu, 2011-05-26 at 19:46 +0300, Luiz Augusto von Dentz wrote:
> Hi Bastien,
> 
> On Thu, May 26, 2011 at 7:12 PM, Bastien Nocera <hadess@hadess.net> wrote:
> > On Thu, 2011-05-26 at 19:00 +0300, Luiz Augusto von Dentz wrote:
> >> Hi Bastien,
> >>
> >> On Thu, May 26, 2011 at 5:50 PM, Bastien Nocera <hadess@hadess.net> wrote:
> >> > On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
> >> >> As discussed on IRC,
> >> >>
> >> >> inotify is now required, and we force hci0 (or the first device) to be
> >> >> named after the pretty hostname.
> >> >>
> >> >> Note that the GATT call isn't removed, it's now done in
> >> >> adapter_update_local_name().
> >> >
> >> > As discussed again, removed the default adapter special casing, and
> >> > we'll just call hci0 with the pretty name.
> >>
> >> Does this means that the user cannot change permanently its adapter
> >> name when pretty hostname is available? In that case I would suggest
> >> having the stored name before pretty name otherwise if bluetoothd is
> >> restarted the adapter name will be reset to pretty hostname again.
> >
> > I don't see that as a problem. In which cases exactly would you want the
> > device name to be different from the pretty hostname?
> 
> Well that change the current behavior which is to restore the last
> name set, so if I set the name to FooBar1 and restart the device I
> want FooBar1 back after boot not pretty hostname, otherwise we can
> just make Name property read-only.

I'd like a use case, not corner cases where things might not work
exactly as you think it should, which I'm guessing there should be
plenty.

> In other words, if we want to be consistent there is only 2 options:
> 
> 1. Allow the user application to change the adapter name, the order
> then should be stored name > pretty hostname > name configured on
> main.conf.
> 
> 2. Do no allow user to change adapter name directly if pretty hostname
> exists, Name property should be made read-only (breaks API?), user can
> only change the adapter name via pretty hostname.

If you don't have a pretty hostname, we use the stored name. I don't
really see the need to have those levels of indirection.

What's the use case for needing to change the adapter name when pretty
hostname is used?


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-26 16:56         ` Bastien Nocera
@ 2011-05-30 12:05           ` Luiz Augusto von Dentz
  2011-05-30 14:50             ` Bastien Nocera
  2011-06-07  9:34             ` [PATCH] adaptername: Move adapter naming into a plugin Bastien Nocera
  0 siblings, 2 replies; 25+ messages in thread
From: Luiz Augusto von Dentz @ 2011-05-30 12:05 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: BlueZ development

Hi Bastien,

On Thu, May 26, 2011 at 7:56 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Thu, 2011-05-26 at 19:46 +0300, Luiz Augusto von Dentz wrote:
>> Hi Bastien,
>>
>> On Thu, May 26, 2011 at 7:12 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> > On Thu, 2011-05-26 at 19:00 +0300, Luiz Augusto von Dentz wrote:
>> >> Hi Bastien,
>> >>
>> >> On Thu, May 26, 2011 at 5:50 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> >> > On Thu, 2011-05-26 at 15:11 +0100, Bastien Nocera wrote:
>> >> >> As discussed on IRC,
>> >> >>
>> >> >> inotify is now required, and we force hci0 (or the first device) to be
>> >> >> named after the pretty hostname.
>> >> >>
>> >> >> Note that the GATT call isn't removed, it's now done in
>> >> >> adapter_update_local_name().
>> >> >
>> >> > As discussed again, removed the default adapter special casing, and
>> >> > we'll just call hci0 with the pretty name.
>> >>
>> >> Does this means that the user cannot change permanently its adapter
>> >> name when pretty hostname is available? In that case I would suggest
>> >> having the stored name before pretty name otherwise if bluetoothd is
>> >> restarted the adapter name will be reset to pretty hostname again.
>> >
>> > I don't see that as a problem. In which cases exactly would you want the
>> > device name to be different from the pretty hostname?
>>
>> Well that change the current behavior which is to restore the last
>> name set, so if I set the name to FooBar1 and restart the device I
>> want FooBar1 back after boot not pretty hostname, otherwise we can
>> just make Name property read-only.
>
> I'd like a use case, not corner cases where things might not work
> exactly as you think it should, which I'm guessing there should be
> plenty.
>
>> In other words, if we want to be consistent there is only 2 options:
>>
>> 1. Allow the user application to change the adapter name, the order
>> then should be stored name > pretty hostname > name configured on
>> main.conf.
>>
>> 2. Do no allow user to change adapter name directly if pretty hostname
>> exists, Name property should be made read-only (breaks API?), user can
>> only change the adapter name via pretty hostname.
>
> If you don't have a pretty hostname, we use the stored name. I don't
> really see the need to have those levels of indirection.
>
> What's the use case for needing to change the adapter name when pretty
> hostname is used?
>
>

Perhaps you are not seeing this problem because at least on gnome3 the
bluetooths settings do not have any option to change the adapter name
anymore, but iirc older gnome versions, KDE and others may still use
adapter.SetProperty.

Im not against it, actually I like the idea of using the pretty
hostname but since there is the possibility to set the Name using
adapter.SetProperty it has to be consistent thus the suggestion to
return an error when the user application attempt to change it using
SetProperty, could you do that?

-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Another pass at adapter naming
  2011-05-30 12:05           ` Luiz Augusto von Dentz
@ 2011-05-30 14:50             ` Bastien Nocera
  2011-06-07  9:34             ` [PATCH] adaptername: Move adapter naming into a plugin Bastien Nocera
  1 sibling, 0 replies; 25+ messages in thread
From: Bastien Nocera @ 2011-05-30 14:50 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: BlueZ development

On Mon, 2011-05-30 at 15:05 +0300, Luiz Augusto von Dentz wrote:
<snip>
> Perhaps you are not seeing this problem because at least on gnome3 the
> bluetooths settings do not have any option to change the adapter name
> anymore, but iirc older gnome versions, KDE and others may still use
> adapter.SetProperty.
> 
> Im not against it, actually I like the idea of using the pretty
> hostname but since there is the possibility to set the Name using
> adapter.SetProperty it has to be consistent thus the suggestion to
> return an error when the user application attempt to change it using
> SetProperty, could you do that?

Right, I see your point. By the way, the GNOME 3 Bluetooth settings
don't have the ability to change the adapter name just because of that
feature, we wanted to do things properly the first time around.

I'll try to get this fixed for the next patch version.

Cheers



^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] adaptername: Move adapter naming into a plugin
  2011-05-30 12:05           ` Luiz Augusto von Dentz
  2011-05-30 14:50             ` Bastien Nocera
@ 2011-06-07  9:34             ` Bastien Nocera
  2011-06-07  9:49               ` Daniele Forsi
  1 sibling, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-06-07  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.dentz, Bastien Nocera

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 |  296 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c         |  119 +++++---------------
 src/adapter.h         |    4 +-
 src/manager.c         |    5 +
 src/manager.h         |    1 +
 7 files changed, 340 insertions(+), 92 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 <sys/inotify.h>.])],
+			   [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..f3156fe
--- /dev/null
+++ b/plugins/adaptername.c
@@ -0,0 +1,296 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#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 <sys/inotify.h>
+#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();
+
+		/* 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;
+
+	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 b189841..b061624 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) */
@@ -186,64 +187,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)
 {
@@ -916,10 +859,13 @@ 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 (adapter->allow_name_changes == FALSE)
+		return -EPERM;
+
 	if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0)
-		return;
+		return 0;
 
 	strncpy(adapter->name, name, MAX_NAME_LENGTH);
 
@@ -938,38 +884,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);
 }
 
@@ -2576,6 +2513,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) {
@@ -2591,14 +2530,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);
@@ -2684,6 +2615,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 3526849..626c9ef 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);
@@ -115,7 +117,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


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-07  9:34             ` [PATCH] adaptername: Move adapter naming into a plugin Bastien Nocera
@ 2011-06-07  9:49               ` Daniele Forsi
  2011-06-07 10:03                 ` Bastien Nocera
  2011-06-07 10:03                 ` Bastien Nocera
  0 siblings, 2 replies; 25+ messages in thread
From: Daniele Forsi @ 2011-06-07  9:49 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth, luiz.dentz

2011/6/7 Bastien Nocera:

> diff --git a/src/adapter.c b/src/adapter.c

> @@ -938,38 +884,29 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)

> +               int err = adapter_ops->set_name(adapter->dev_id, name);
> +               if (err < 0)
> +                       return -err;

this should be:
return err;
else the error isn't detected in the calling code:
> +       err = adapter_update_local_name (adapter, name);
> +       if (err < 0)
> +               return btd_error_failed(msg, strerror(-err));

-- 
Daniele Forsi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-07  9:49               ` Daniele Forsi
@ 2011-06-07 10:03                 ` Bastien Nocera
  2011-06-08 16:13                   ` Anderson Lizardo
  2011-06-07 10:03                 ` Bastien Nocera
  1 sibling, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-06-07 10:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.dentz, Bastien Nocera

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 |  296 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c         |  119 +++++---------------
 src/adapter.h         |    4 +-
 src/manager.c         |    5 +
 src/manager.h         |    1 +
 7 files changed, 340 insertions(+), 92 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 <sys/inotify.h>.])],
+			   [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..f3156fe
--- /dev/null
+++ b/plugins/adaptername.c
@@ -0,0 +1,296 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#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 <sys/inotify.h>
+#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();
+
+		/* 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;
+
+	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 b189841..87af784 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) */
@@ -186,64 +187,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)
 {
@@ -916,10 +859,13 @@ 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 (adapter->allow_name_changes == FALSE)
+		return -EPERM;
+
 	if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0)
-		return;
+		return 0;
 
 	strncpy(adapter->name, name, MAX_NAME_LENGTH);
 
@@ -938,38 +884,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);
 }
 
@@ -2576,6 +2513,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) {
@@ -2591,14 +2530,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);
@@ -2684,6 +2615,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 3526849..626c9ef 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);
@@ -115,7 +117,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


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-07  9:49               ` Daniele Forsi
  2011-06-07 10:03                 ` Bastien Nocera
@ 2011-06-07 10:03                 ` Bastien Nocera
  1 sibling, 0 replies; 25+ messages in thread
From: Bastien Nocera @ 2011-06-07 10:03 UTC (permalink / raw)
  To: Daniele Forsi; +Cc: linux-bluetooth, luiz.dentz

On Tue, 2011-06-07 at 11:49 +0200, Daniele Forsi wrote:
> 2011/6/7 Bastien Nocera:
> 
> > diff --git a/src/adapter.c b/src/adapter.c
> 
> > @@ -938,38 +884,29 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)
> 
> > +               int err = adapter_ops->set_name(adapter->dev_id, name);
> > +               if (err < 0)
> > +                       return -err;
> 
> this should be:
> return err;
> else the error isn't detected in the calling code:

Good catch, fixed now.

> > +       err = adapter_update_local_name (adapter, name);
> > +       if (err < 0)
> > +               return btd_error_failed(msg, strerror(-err));
> 



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-07 10:03                 ` Bastien Nocera
@ 2011-06-08 16:13                   ` Anderson Lizardo
  2011-06-08 17:38                     ` Bastien Nocera
  2011-06-08 17:43                     ` Bastien Nocera
  0 siblings, 2 replies; 25+ messages in thread
From: Anderson Lizardo @ 2011-06-08 16:13 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth, luiz.dentz

Hi Bastien,

On Tue, Jun 7, 2011 at 6:03 AM, Bastien Nocera <hadess@hadess.net> wrote:
> +static char *read_pretty_host_name (void)

Unnecessary space before "(".

> +{
> +       char *contents, *ret;
> +       char **lines;
> +       guint i;
> +
> +       ret = NULL;

You can postpone the attribution above to where it is necessary
(before the for()).

> +
> +       if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE,

I wonder if it would be better to use the autoconf variable for
"/etc/" instead of MACHINE_INFO_DIR.

> +                       &contents, NULL, NULL) == FALSE) {
> +               return NULL;
> +       }

Unnecessary {} on the if() above.

> +       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="));

Maybe it is also good to strip whitespaces before/after the string as
well (there is a glib function for that).

> +                       break;
> +               }
> +       }
> +
> +       g_strfreev(lines);

Missing empty line here.

> +       return ret;
> +}
> [...]
> +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();
> +
> +               /* 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);

Unnecessary whitespace before "(".

> +                       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);
> +       }

Unnecessary {} on the if() above.

> +       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];

Unnecessary spaces between "&"

> +
> +               /* check that it's ours */
> +               if (pevent->len &&
> +                   pevent->name != NULL &&
> +                   strcmp(pevent->name, MACHINE_INFO_FILE) == 0) {
> +                       changed = TRUE;
> +               }

Unnecessary {} on the if() above.

> +               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);

Unnecessary space before first "(".

> +       }
> +
> +       return TRUE;
> +}
> +
> +static void adaptername_remove(struct btd_adapter *adapter)
> +{
> +       if (watch_fd >= 0)
> +               close (watch_fd);

Unnecessary whitespace before "(".

> +       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) {

You can invert the logic of the ret check and drop the if().

> +               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);

Indentation seems broken on the line above. Also two lines with
unnecessary space before "(".

> +               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)
>[...]
> @@ -938,38 +884,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;

This looks incorrect. If the if() is entered, adapter->name_stored is
set to TRUE and right after to FALSE.

> +       }
> +
>        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);

Unnecessary whitespace before "(".

> +       if (err < 0)
> +               return btd_error_failed(msg, strerror(-err));
>
> -done:
>        return dbus_message_new_method_return(msg);
>  }
>
> @@ -2576,6 +2513,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) {
> @@ -2591,14 +2530,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));

I can't find where you moved the attrib_gap_set() call to. This is
necessary for GATT attribute server.

> -
>        sdp_init_services_list(&adapter->bdaddr);
>        load_drivers(adapter);
>        clear_blocked(adapter);
> @@ -2684,6 +2615,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 3526849..626c9ef 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);
> @@ -115,7 +117,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)

Unnecessary whitespace before "(". Also I've seem a patch sent to this
list a while ago with this change.

> +{
> +       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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-08 16:13                   ` Anderson Lizardo
@ 2011-06-08 17:38                     ` Bastien Nocera
  2011-06-14  8:07                       ` Johan Hedberg
  2011-06-08 17:43                     ` Bastien Nocera
  1 sibling, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-06-08 17:38 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth, luiz.dentz, Bastien Nocera

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 |  293 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c         |  118 +++++---------------
 src/adapter.h         |    4 +-
 src/manager.c         |    5 +
 src/manager.h         |    1 +
 7 files changed, 335 insertions(+), 93 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 <sys/inotify.h>.])],
+			   [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..85f9dae
--- /dev/null
+++ b/plugins/adaptername.c
@@ -0,0 +1,293 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#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 <sys/inotify.h>
+#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 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_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);
+	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 b189841..1120c18 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) */
@@ -186,64 +187,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)
 {
@@ -916,10 +859,13 @@ 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 (adapter->allow_name_changes == FALSE)
+		return -EPERM;
+
 	if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0)
-		return;
+		return 0;
 
 	strncpy(adapter->name, name, MAX_NAME_LENGTH);
 
@@ -931,6 +877,7 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)
 		char *name_ptr = adapter->name;
 
 		write_local_name(&adapter->bdaddr, adapter->name);
+		adapter->name_stored = TRUE;
 
 		if (connection)
 			emit_property_changed(connection, adapter->path,
@@ -938,38 +885,25 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)
 						DBUS_TYPE_STRING, &name_ptr);
 	}
 
-	adapter->name_stored = FALSE;
+	if (adapter->up) {
+		int err = adapter_ops->set_name(adapter->dev_id, name);
+		if (err < 0)
+			return err;
+	}
+
+	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);
 }
 
@@ -2576,6 +2510,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) {
@@ -2591,14 +2527,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);
@@ -2684,6 +2612,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 3526849..626c9ef 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);
@@ -115,7 +117,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..42e316c 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_id(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..52bf36b 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_id(void);
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-08 16:13                   ` Anderson Lizardo
  2011-06-08 17:38                     ` Bastien Nocera
@ 2011-06-08 17:43                     ` Bastien Nocera
  2011-06-08 19:30                       ` Anderson Lizardo
  1 sibling, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-06-08 17:43 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth, luiz.dentz

On Wed, 2011-06-08 at 12:13 -0400, Anderson Lizardo wrote:
> Hi Bastien,
> 
> On Tue, Jun 7, 2011 at 6:03 AM, Bastien Nocera <hadess@hadess.net> wrote:
<snip>
> > +
> > +       if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE,
> 
> I wonder if it would be better to use the autoconf variable for
> "/etc/" instead of MACHINE_INFO_DIR.

I'm not sure that'd be any help. Even if bluez is installed in /opt/usr/
or something, the /etc/machine-info is still the canonical location of
that file.

<snip>
> Maybe it is also good to strip whitespaces before/after the string as
> well (there is a glib function for that).

We already strip the whitespaces when setting the adapter name, but I'll
gladly add that if you think it's important.

<snip>
> > @@ -938,38 +884,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;
> 
> This looks incorrect. If the if() is entered, adapter->name_stored is
> set to TRUE and right after to FALSE.

I think I fixed this, otherwise it's me not understanding what
adapter->name_stored is supposed to flag. If it's whether the adapter
name was written to /var/lib/bluetooth/.../config, then we could
probably simplify this code.
<snip>
> > -       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));
> 
> I can't find where you moved the attrib_gap_set() call to. This is
> necessary for GATT attribute server.

Check the code instead of the patch, it's already done in
adapter_update_local_name().
<snip>
> > 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)
> 
> Unnecessary whitespace before "(". Also I've seem a patch sent to this
> list a while ago with this change.

That's Antonio's patch, but it returns the adapter struct, not the ID. I
changed the function name, so both can coexist (as both are needed).

Updated patch sent.

Cheers


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-08 17:43                     ` Bastien Nocera
@ 2011-06-08 19:30                       ` Anderson Lizardo
  0 siblings, 0 replies; 25+ messages in thread
From: Anderson Lizardo @ 2011-06-08 19:30 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth, luiz.dentz

Hi Bastien,

On Wed, Jun 8, 2011 at 1:43 PM, Bastien Nocera <hadess@hadess.net> wrote:
> <snip>
>> > -       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));
>>
>> I can't find where you moved the attrib_gap_set() call to. This is
>> necessary for GATT attribute server.
>
> Check the code instead of the patch, it's already done in
> adapter_update_local_name().

In this case, it is better if you put this cleanup/refactor in a
separate patch. IMHO, you are doing two things on the same patch:

1) moving things to a plugin and removing duplicated code.
2) adding support for /etc/machine-info

These could be split in two patches. This facilitates tracking
regressions (if any) later by bisect.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-08 17:38                     ` Bastien Nocera
@ 2011-06-14  8:07                       ` Johan Hedberg
  2011-06-14  9:18                         ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Johan Hedberg @ 2011-06-14  8:07 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Anderson Lizardo, linux-bluetooth, luiz.dentz

Hi Bastien,

On Wed, Jun 08, 2011, Bastien Nocera wrote:
> +++ b/plugins/adaptername.c
> @@ -0,0 +1,293 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>

You sure you don't want to add your own copyright here? Marcel's
copyright is justified due to copied portions of the file, but the
amount of new code that you're adding would also entitle you to add your
own declaration.

> +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_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;
> +	}

Since this is a quite large if-branch and the only exit from it is the
"return 0;" statement, I think it's a quite good indication that the
code should be in its own function (it'll also help you with following
the max 79 characters per line rule).

> +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) {

The two above line mix tabs and spaces for indentation. Please only use
tabs.

> +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);

Same here (two above lines).

> +	if (watch_fd < 0) {
> +		error("Failed to setup watch for '%s'",
> +		      MACHINE_INFO_DIR);

And here.

> -	adapter->name_stored = FALSE;
> +	if (adapter->up) {
> +		int err = adapter_ops->set_name(adapter->dev_id, name);
> +		if (err < 0)
> +			return err;
> +	}
> +
> +	return 0;

This could simply be:

	if (adapter->up)
		return adapter_ops->set_name(adapter->dev_id, name);

	return 0;

Other than that I didn't find any major issues, however please consider
the suggestion from Lizardo to split the patch in two parts.

Johan

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-14  8:07                       ` Johan Hedberg
@ 2011-06-14  9:18                         ` Bastien Nocera
  2011-06-14  9:43                           ` Johan Hedberg
  0 siblings, 1 reply; 25+ messages in thread
From: Bastien Nocera @ 2011-06-14  9:18 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: Anderson Lizardo, linux-bluetooth, luiz.dentz

On Tue, 2011-06-14 at 11:07 +0300, Johan Hedberg wrote:
> Hi Bastien,
<snip>
> This could simply be:
> 
> 	if (adapter->up)
> 		return adapter_ops->set_name(adapter->dev_id, name);
> 
> 	return 0;
> 
> Other than that I didn't find any major issues, however please consider
> the suggestion from Lizardo to split the patch in two parts.

I already sent the split patches (2 of them) last week:
http://thread.gmane.org/gmane.linux.bluez.kernel/13621

 I think this is an indication that a mailing-list isn't that good a
tracking tool...

Cheers


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-14  9:18                         ` Bastien Nocera
@ 2011-06-14  9:43                           ` Johan Hedberg
  2011-06-15 10:18                             ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Johan Hedberg @ 2011-06-14  9:43 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Anderson Lizardo, linux-bluetooth, luiz.dentz

Hi Bastien,

On Tue, Jun 14, 2011, Bastien Nocera wrote:
> On Tue, 2011-06-14 at 11:07 +0300, Johan Hedberg wrote:
> > Hi Bastien,
> <snip>
> > This could simply be:
> > 
> > 	if (adapter->up)
> > 		return adapter_ops->set_name(adapter->dev_id, name);
> > 
> > 	return 0;
> > 
> > Other than that I didn't find any major issues, however please consider
> > the suggestion from Lizardo to split the patch in two parts.
> 
> I already sent the split patches (2 of them) last week:
> http://thread.gmane.org/gmane.linux.bluez.kernel/13621

No, I did notice that thread. It's not a split of this patch. For one
thing it doesn't contain any adaptername plugin at all.

What about the coding style issues I pointed out?

I also need to look more carefully into the name_stored change. I'm not
sure you completely understood its significance. This is also a change
which doesn't exist in your original patch (again confirming that the
new thread is *not* a split of the original patch).

Johan

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-14  9:43                           ` Johan Hedberg
@ 2011-06-15 10:18                             ` Bastien Nocera
  2011-06-15 13:00                               ` Anderson Lizardo
  2011-06-15 21:04                               ` Johan Hedberg
  0 siblings, 2 replies; 25+ messages in thread
From: Bastien Nocera @ 2011-06-15 10:18 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: Anderson Lizardo, linux-bluetooth, luiz.dentz

On Tue, 2011-06-14 at 12:43 +0300, Johan Hedberg wrote:
> Hi Bastien,
> 
> On Tue, Jun 14, 2011, Bastien Nocera wrote:
> > On Tue, 2011-06-14 at 11:07 +0300, Johan Hedberg wrote:
> > > Hi Bastien,
> > <snip>
> > > This could simply be:
> > > 
> > > 	if (adapter->up)
> > > 		return adapter_ops->set_name(adapter->dev_id, name);
> > > 
> > > 	return 0;
> > > 
> > > Other than that I didn't find any major issues, however please consider
> > > the suggestion from Lizardo to split the patch in two parts.
> > 
> > I already sent the split patches (2 of them) last week:
> > http://thread.gmane.org/gmane.linux.bluez.kernel/13621
> 
> No, I did notice that thread. It's not a split of this patch. For one
> thing it doesn't contain any adaptername plugin at all.

I know. I mentioned on IRC that I would work on the adaptername plugin
once those 2 patches went in. I'm getting a little bit sick of spinning
patches that get reviewed when I don't have time. A month to get patches
into bluez isn't my idea of fun.

> What about the coding style issues I pointed out?
> 
> I also need to look more carefully into the name_stored change. I'm not
> sure you completely understood its significance.

The significance is to avoid writing the adapter name to disk when it
hasn't changed. Given that we only ever write the adapter name to disk
in one location, and we check whether it's been changed, then the
variable is useless.

>  This is also a change
> which doesn't exist in your original patch (again confirming that the
> new thread is *not* a split of the original patch).

I *obviously* can't split the original patch in 2 patches and keep the
code working. Lizardo wanted the simplification of the name setting and
the adaptername plugin patch to be separate so that we could potentially
bisect regressions.

Feel free to discuss it between yourselves.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-15 10:18                             ` Bastien Nocera
@ 2011-06-15 13:00                               ` Anderson Lizardo
  2011-06-15 21:04                               ` Johan Hedberg
  1 sibling, 0 replies; 25+ messages in thread
From: Anderson Lizardo @ 2011-06-15 13:00 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Johan Hedberg, linux-bluetooth, luiz.dentz

Hi,

On Wed, Jun 15, 2011 at 6:18 AM, Bastien Nocera <hadess@hadess.net> wrote:
> I *obviously* can't split the original patch in 2 patches and keep the
> code working. Lizardo wanted the simplification of the name setting and
> the adaptername plugin patch to be separate so that we could potentially
> bisect regressions.

"wanted" is a bit too much IMHO. It was a suggestion based on my own
review. In the end it is up to the commiters of the project (Johan &
Marcel ?) to decide whether to accept/reject the patches.

My suggestion was to simply split between "move adapter naming into a
plugin" (like the description of your original patch) and "add support
for pretty hostnames from systemd". Currently both things are done in
a single patch.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-15 10:18                             ` Bastien Nocera
  2011-06-15 13:00                               ` Anderson Lizardo
@ 2011-06-15 21:04                               ` Johan Hedberg
  2011-07-19 11:26                                 ` Luiz Augusto von Dentz
  1 sibling, 1 reply; 25+ messages in thread
From: Johan Hedberg @ 2011-06-15 21:04 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Anderson Lizardo, linux-bluetooth, luiz.dentz

Hi Bastien,

On Wed, Jun 15, 2011, Bastien Nocera wrote:
> > > I already sent the split patches (2 of them) last week:
> > > http://thread.gmane.org/gmane.linux.bluez.kernel/13621
> > 
> > No, I did notice that thread. It's not a split of this patch. For one
> > thing it doesn't contain any adaptername plugin at all.
> 
> I know. I mentioned on IRC that I would work on the adaptername plugin
> once those 2 patches went in. I'm getting a little bit sick of spinning
> patches that get reviewed when I don't have time. A month to get patches
> into bluez isn't my idea of fun.

I understand that and I'm sorry that the process has taken so long. I'm
mostly to blame, though a considerable part of the reason is that you're
not adding or touching some peripheral piece of code here but
fundamental core functionality that will inevitably take longer to
discuss and review compared other patches.

> > I also need to look more carefully into the name_stored change. I'm not
> > sure you completely understood its significance.
> 
> The significance is to avoid writing the adapter name to disk when it
> hasn't changed. Given that we only ever write the adapter name to disk
> in one location, and we check whether it's been changed, then the
> variable is useless.

Good. I just wanted to make sure that you're familiar with commit
eb3efee1 (that introduced this variable) and the use-case its commit
message describes, that you realize that a name write will trigger a
name read (in hciops) which in turn will trigger a new call to
adapter_update_local_name, and that part of all this is also to try to
support 3rd party name changers like hciconfig (not a very high priority
goal though).

> >  This is also a change
> > which doesn't exist in your original patch (again confirming that the
> > new thread is *not* a split of the original patch).
> 
> I *obviously* can't split the original patch in 2 patches and keep the
> code working. Lizardo wanted the simplification of the name setting and
> the adaptername plugin patch to be separate so that we could potentially
> bisect regressions.

I'll attribute it to your frustration with the tardiness of this process
that you don't seem to have the will or interest to understand what I
was trying to say. As Lizardo already clarified the proposed split was
about first moving the existing functionality/code to the new plugin and
then adding the prettyname support. The final outcome would then contain
the same functionality as the original patch and the code would "keep
working" at every step. Since neither of the new patches you sent
contained the adaptername plugin I concluded that it was something else
than the proposed split.

Btw, the get_default_adapter patch is now in so you can base the rest of
your patches on top of that.

Johan

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-06-15 21:04                               ` Johan Hedberg
@ 2011-07-19 11:26                                 ` Luiz Augusto von Dentz
  2011-07-19 11:35                                   ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 25+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-19 11:26 UTC (permalink / raw)
  To: Bastien Nocera, Anderson Lizardo, linux-bluetooth, luiz.dentz

Hi Bastien,

Apparently there is something wrong when removing last adapter
bluetoothd start burning cpu, disabling adaptername fix the problem so
there might be something wrong in adapter remove callback, can you
take a look? Btw, Im using rawhide so I suppose adaptername should
work, right?

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-07-19 11:26                                 ` Luiz Augusto von Dentz
@ 2011-07-19 11:35                                   ` Luiz Augusto von Dentz
  2011-07-19 12:35                                     ` Bastien Nocera
  0 siblings, 1 reply; 25+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-19 11:35 UTC (permalink / raw)
  To: Bastien Nocera, Anderson Lizardo, linux-bluetooth, luiz.dentz

Hi Bastien,

On Tue, Jul 19, 2011 at 2:26 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Bastien,
>
> Apparently there is something wrong when removing last adapter
> bluetoothd start burning cpu, disabling adaptername fix the problem so
> there might be something wrong in adapter remove callback, can you
> take a look? Btw, Im using rawhide so I suppose adaptername should
> work, right?


It seems .remove is closing and removing the watch for every adapter
but the watch is initialized in the plugin init so it is not really
per-adapter, so I moved to .exit:

diff --git a/plugins/adaptername.c b/plugins/adaptername.c
index 2a54cc0..9e99e6a 100644
--- a/plugins/adaptername.c
+++ b/plugins/adaptername.c
@@ -262,10 +262,6 @@ static gboolean handle_inotify_cb(GIOChannel
*channel, GIOCondition cond,

 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 = {
@@ -314,6 +310,13 @@ static int adaptername_init(void)

 static void adaptername_exit(void)
 {
+       if (watch_fd >= 0)
+               close(watch_fd);
+       if (inotify != NULL) {
+               g_io_channel_shutdown(inotify, FALSE, NULL);
+               g_io_channel_unref(inotify);
+       }
+
        btd_unregister_adapter_driver(&adaptername_driver);
 }


It seems to work fine.

-- 
Luiz Augusto von Dentz

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] adaptername: Move adapter naming into a plugin
  2011-07-19 11:35                                   ` Luiz Augusto von Dentz
@ 2011-07-19 12:35                                     ` Bastien Nocera
  0 siblings, 0 replies; 25+ messages in thread
From: Bastien Nocera @ 2011-07-19 12:35 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Anderson Lizardo, linux-bluetooth

On Tue, 2011-07-19 at 14:35 +0300, Luiz Augusto von Dentz wrote:
> Hi Bastien,
> 
> On Tue, Jul 19, 2011 at 2:26 PM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
> > Hi Bastien,
> >
> > Apparently there is something wrong when removing last adapter
> > bluetoothd start burning cpu, disabling adaptername fix the problem so
> > there might be something wrong in adapter remove callback, can you
> > take a look? Btw, Im using rawhide so I suppose adaptername should
> > work, right?
> 
> 
> It seems .remove is closing and removing the watch for every adapter
> but the watch is initialized in the plugin init so it is not really
> per-adapter, so I moved to .exit:

You're completely correct here. My mistake.


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2011-07-19 12:35 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-26 14:11 Another pass at adapter naming Bastien Nocera
2011-05-26 14:50 ` Bastien Nocera
2011-05-26 16:00   ` Luiz Augusto von Dentz
2011-05-26 16:12     ` Bastien Nocera
2011-05-26 16:46       ` Luiz Augusto von Dentz
2011-05-26 16:56         ` Bastien Nocera
2011-05-30 12:05           ` Luiz Augusto von Dentz
2011-05-30 14:50             ` Bastien Nocera
2011-06-07  9:34             ` [PATCH] adaptername: Move adapter naming into a plugin Bastien Nocera
2011-06-07  9:49               ` Daniele Forsi
2011-06-07 10:03                 ` Bastien Nocera
2011-06-08 16:13                   ` Anderson Lizardo
2011-06-08 17:38                     ` Bastien Nocera
2011-06-14  8:07                       ` Johan Hedberg
2011-06-14  9:18                         ` Bastien Nocera
2011-06-14  9:43                           ` Johan Hedberg
2011-06-15 10:18                             ` Bastien Nocera
2011-06-15 13:00                               ` Anderson Lizardo
2011-06-15 21:04                               ` Johan Hedberg
2011-07-19 11:26                                 ` Luiz Augusto von Dentz
2011-07-19 11:35                                   ` Luiz Augusto von Dentz
2011-07-19 12:35                                     ` Bastien Nocera
2011-06-08 17:43                     ` Bastien Nocera
2011-06-08 19:30                       ` Anderson Lizardo
2011-06-07 10:03                 ` Bastien Nocera

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.