OSDN Git Service

plugins: Add support for systemd's hostname daemon
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 29 Dec 2012 22:46:19 +0000 (14:46 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Sat, 29 Dec 2012 22:46:19 +0000 (14:46 -0800)
Makefile.plugins
plugins/hostname.c [new file with mode: 0644]

index c4670d8..c3506d9 100644 (file)
@@ -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 (file)
index 0000000..4809366
--- /dev/null
@@ -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)