diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-12-29 14:46:19 -0800 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-12-29 14:46:19 -0800 |
commit | 7279e8508ef1f6ba62a5f343b870bbcd54efbef4 (patch) | |
tree | afaaffc1370d85e65611917d2e496649f5547ab5 /plugins/hostname.c | |
parent | c6748fd887d08388ee43f6015d95ec8daa87ae8e (diff) | |
download | bluez-7279e8508ef1f6ba62a5f343b870bbcd54efbef4.tar.gz |
plugins: Add support for systemd's hostname daemon
Diffstat (limited to 'plugins/hostname.c')
-rw-r--r-- | plugins/hostname.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/plugins/hostname.c b/plugins/hostname.c new file mode 100644 index 000000000..480936620 --- /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) |