Diff between c6748fd887d08388ee43f6015d95ec8daa87ae8e and 7279e8508ef1f6ba62a5f343b870bbcd54efbef4

Changed Files

File Additions Deletions Status
Makefile.plugins +3 -0 modified
plugins/hostname.c +214 -0 added

Full Patch

diff --git a/Makefile.plugins b/Makefile.plugins
index c4670d8..c3506d9 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -1,4 +1,7 @@
 
+builtin_modules += hostname
+builtin_sources += plugins/hostname.c
+
 builtin_modules += formfactor
 builtin_sources += plugins/formfactor.c
 
diff --git a/plugins/hostname.c b/plugins/hostname.c
new file mode 100644
index 0000000..4809366
--- /dev/null
+++ b/plugins/hostname.c
@@ -0,0 +1,214 @@
+/*
+ *
+ *  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 <errno.h>
+#include <stdint.h>
+#include <gdbus/gdbus.h>
+
+#include "dbus-common.h"
+#include "plugin.h"
+#include "adapter.h"
+#include "manager.h"
+#include "log.h"
+
+/* http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm */
+
+#define MAJOR_CLASS_MISCELLANEOUS	0x00
+#define MAJOR_CLASS_COMPUTER		0x01
+
+#define MINOR_CLASS_UNCATEGORIZED	0x00
+#define MINOR_CLASS_DESKTOP		0x01
+#define MINOR_CLASS_SERVER		0x02
+#define MINOR_CLASS_LAPTOP		0x03
+#define MINOR_CLASS_HANDHELD		0x04
+#define MINOR_CLASS_PALM_SIZED		0x05
+#define MINOR_CLASS_WEARABLE		0x06
+#define MINOR_CLASS_TABLET		0x07
+
+static uint8_t major_class = MAJOR_CLASS_MISCELLANEOUS;
+static uint8_t minor_class = MINOR_CLASS_UNCATEGORIZED;
+
+static char *pretty_hostname = NULL;
+
+static void update_name(struct btd_adapter *adapter, gpointer user_data)
+{
+	if (pretty_hostname == NULL)
+		return;
+
+	DBG("name: %s", pretty_hostname);
+
+	adapter_set_allow_name_changes(adapter, FALSE);
+	adapter_set_name(adapter, pretty_hostname);
+}
+
+static void update_class(struct btd_adapter *adapter, gpointer user_data)
+{
+	if (major_class == MAJOR_CLASS_MISCELLANEOUS)
+		return;
+
+	DBG("major: 0x%02x minor: 0x%02x", major_class, minor_class);
+
+	btd_adapter_set_class(adapter, major_class, minor_class);
+}
+
+static const struct {
+	const char *chassis;
+	uint8_t major_class;
+	uint8_t minor_class;
+} chassis_table[] = {
+	{ "desktop",  MAJOR_CLASS_COMPUTER, MINOR_CLASS_DESKTOP  },
+	{ "server",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_SERVER   },
+	{ "laptop",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_LAPTOP   },
+	{ "handset",  MAJOR_CLASS_COMPUTER, MINOR_CLASS_HANDHELD },
+	{ "tablet",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_TABLET   },
+	{ }
+};
+
+static void property_changed(GDBusProxy *proxy, const char *name,
+					DBusMessageIter *iter, void *user_data)
+{
+	if (g_str_equal(name, "PrettyHostname") == TRUE) {
+		if (iter == NULL) {
+			g_dbus_proxy_refresh_property(proxy, name);
+			return;
+		}
+
+		if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
+			const char *str;
+
+			dbus_message_iter_get_basic(iter, &str);
+
+			DBG("pretty hostname: %s", str);
+
+			g_free(pretty_hostname);
+			pretty_hostname = g_strdup(str);
+
+			manager_foreach_adapter(update_name, NULL);
+		}
+	} else if (g_str_equal(name, "Chassis") == TRUE) {
+		if (iter == NULL) {
+			g_dbus_proxy_refresh_property(proxy, name);
+			return;
+		}
+
+		if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
+			const char *str;
+			int i;
+
+			dbus_message_iter_get_basic(iter, &str);
+
+			DBG("chassis: %s", str);
+
+			for (i = 0; chassis_table[i].chassis; i++) {
+				if (strcmp(chassis_table[i].chassis, str))
+					continue;
+
+				major_class = chassis_table[i].major_class;
+				minor_class = chassis_table[i].minor_class;
+
+				manager_foreach_adapter(update_class, NULL);
+				break;
+			}
+		}
+	}
+}
+
+static int hostname_probe(struct btd_adapter *adapter)
+{
+	DBG("");
+
+	update_name(adapter, NULL);
+	update_class(adapter, NULL);
+
+	return 0;
+}
+
+static void hostname_remove(struct btd_adapter *adapter)
+{
+	DBG("");
+}
+
+static struct btd_adapter_driver hostname_driver = {
+	.name	= "hostname",
+	.probe	= hostname_probe,
+	.remove	= hostname_remove,
+};
+
+static GDBusClient *hostname_client = NULL;
+static GDBusProxy *hostname_proxy = NULL;
+
+static int hostname_init(void)
+{
+	DBusConnection *conn = btd_get_dbus_connection();
+	int err;
+
+	hostname_client = g_dbus_client_new(conn, "org.freedesktop.hostname1",
+						"/org/freedesktop/hostname1");
+	if (!hostname_client)
+		return -EIO;
+
+	hostname_proxy = g_dbus_proxy_new(hostname_client,
+						"/org/freedesktop/hostname1",
+						"org.freedesktop.hostname1");
+	if (!hostname_proxy) {
+		g_dbus_client_unref(hostname_client);
+		hostname_client = NULL;
+		return -EIO;
+	}
+
+	g_dbus_proxy_set_property_watch(hostname_proxy, property_changed, NULL);
+
+	err = btd_register_adapter_driver(&hostname_driver);
+	if (err < 0) {
+		g_dbus_proxy_unref(hostname_proxy);
+		hostname_proxy = NULL;
+		g_dbus_client_unref(hostname_client);
+		hostname_client = NULL;
+	}
+
+	return err;
+}
+
+static void hostname_exit(void)
+{
+	btd_unregister_adapter_driver(&hostname_driver);
+
+	if (hostname_proxy) {
+		g_dbus_proxy_unref(hostname_proxy);
+		hostname_proxy = NULL;
+	}
+
+	if (hostname_client) {
+		g_dbus_client_unref(hostname_client);
+		hostname_client = NULL;
+	}
+
+	g_free(pretty_hostname);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(hostname, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+						hostname_init, hostname_exit)