Blame plugins/hostname.c

Packit Service 8264ee
/*
Packit Service 8264ee
 *
Packit Service 8264ee
 *  BlueZ - Bluetooth protocol stack for Linux
Packit Service 8264ee
 *
Packit Service 8264ee
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
Packit Service 8264ee
 *
Packit Service 8264ee
 *
Packit Service 8264ee
 *  This program is free software; you can redistribute it and/or modify
Packit Service 8264ee
 *  it under the terms of the GNU General Public License as published by
Packit Service 8264ee
 *  the Free Software Foundation; either version 2 of the License, or
Packit Service 8264ee
 *  (at your option) any later version.
Packit Service 8264ee
 *
Packit Service 8264ee
 *  This program is distributed in the hope that it will be useful,
Packit Service 8264ee
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 8264ee
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 8264ee
 *  GNU General Public License for more details.
Packit Service 8264ee
 *
Packit Service 8264ee
 *  You should have received a copy of the GNU General Public License
Packit Service 8264ee
 *  along with this program; if not, write to the Free Software
Packit Service 8264ee
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service 8264ee
 *
Packit Service 8264ee
 */
Packit Service 8264ee
Packit Service 8264ee
#ifdef HAVE_CONFIG_H
Packit Service 8264ee
#include <config.h>
Packit Service 8264ee
#endif
Packit Service 8264ee
Packit Service 8264ee
#include <errno.h>
Packit Service 8264ee
#include <stdint.h>
Packit Service 8264ee
#include <stdlib.h>
Packit Service 8264ee
#include <string.h>
Packit Service 8264ee
Packit Service 8264ee
#include "lib/bluetooth.h"
Packit Service 8264ee
#include "lib/sdp.h"
Packit Service 8264ee
Packit Service 8264ee
#include "gdbus/gdbus.h"
Packit Service 8264ee
Packit Service 8264ee
#include "src/dbus-common.h"
Packit Service 8264ee
#include "src/plugin.h"
Packit Service 8264ee
#include "src/adapter.h"
Packit Service 8264ee
#include "src/log.h"
Packit Service 8264ee
Packit Service 8264ee
/* http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm */
Packit Service 8264ee
Packit Service 8264ee
#define MAJOR_CLASS_MISCELLANEOUS	0x00
Packit Service 8264ee
#define MAJOR_CLASS_COMPUTER		0x01
Packit Service 8264ee
Packit Service 8264ee
#define MINOR_CLASS_UNCATEGORIZED	0x00
Packit Service 8264ee
#define MINOR_CLASS_DESKTOP		0x01
Packit Service 8264ee
#define MINOR_CLASS_SERVER		0x02
Packit Service 8264ee
#define MINOR_CLASS_LAPTOP		0x03
Packit Service 8264ee
#define MINOR_CLASS_HANDHELD		0x04
Packit Service 8264ee
#define MINOR_CLASS_PALM_SIZED		0x05
Packit Service 8264ee
#define MINOR_CLASS_WEARABLE		0x06
Packit Service 8264ee
#define MINOR_CLASS_TABLET		0x07
Packit Service 8264ee
Packit Service 8264ee
static uint8_t major_class = MAJOR_CLASS_MISCELLANEOUS;
Packit Service 8264ee
static uint8_t minor_class = MINOR_CLASS_UNCATEGORIZED;
Packit Service 8264ee
Packit Service 8264ee
static char *pretty_hostname = NULL;
Packit Service 8264ee
static char *static_hostname = NULL;
Packit Service 8264ee
Packit Service 8264ee
/*
Packit Service 8264ee
 * Fallback to static hostname only if empty pretty hostname was already
Packit Service 8264ee
 * received.
Packit Service 8264ee
 */
Packit Service 8264ee
static const char *get_hostname(void)
Packit Service 8264ee
{
Packit Service 8264ee
	if (pretty_hostname) {
Packit Service 8264ee
		if (g_str_equal(pretty_hostname, "") == FALSE)
Packit Service 8264ee
			return pretty_hostname;
Packit Service 8264ee
Packit Service 8264ee
		if (static_hostname &&
Packit Service 8264ee
				g_str_equal(static_hostname, "") == FALSE)
Packit Service 8264ee
			return static_hostname;
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	return NULL;
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static void update_name(struct btd_adapter *adapter, gpointer user_data)
Packit Service 8264ee
{
Packit Service 8264ee
	const char *hostname = get_hostname();
Packit Service 8264ee
Packit Service 8264ee
	if (hostname == NULL)
Packit Service 8264ee
		return;
Packit Service 8264ee
Packit Service 8264ee
	if (btd_adapter_is_default(adapter)) {
Packit Service 8264ee
		DBG("name: %s", hostname);
Packit Service 8264ee
Packit Service 8264ee
		adapter_set_name(adapter, hostname);
Packit Service 8264ee
	} else {
Packit Service 8264ee
		uint16_t index = btd_adapter_get_index(adapter);
Packit Service 8264ee
		char *str;
Packit Service 8264ee
Packit Service 8264ee
		/* Avoid "some device #0" names, start at #1 */
Packit Service 8264ee
		str = g_strdup_printf("%s #%u", hostname, index + 1);
Packit Service 8264ee
Packit Service 8264ee
		DBG("name: %s", str);
Packit Service 8264ee
Packit Service 8264ee
		adapter_set_name(adapter, str);
Packit Service 8264ee
Packit Service 8264ee
		g_free(str);
Packit Service 8264ee
	}
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static void update_class(struct btd_adapter *adapter, gpointer user_data)
Packit Service 8264ee
{
Packit Service 8264ee
	if (major_class == MAJOR_CLASS_MISCELLANEOUS)
Packit Service 8264ee
		return;
Packit Service 8264ee
Packit Service 8264ee
	DBG("major: 0x%02x minor: 0x%02x", major_class, minor_class);
Packit Service 8264ee
Packit Service 8264ee
	btd_adapter_set_class(adapter, major_class, minor_class);
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static const struct {
Packit Service 8264ee
	const char *chassis;
Packit Service 8264ee
	uint8_t major_class;
Packit Service 8264ee
	uint8_t minor_class;
Packit Service 8264ee
} chassis_table[] = {
Packit Service 8264ee
	{ "desktop",  MAJOR_CLASS_COMPUTER, MINOR_CLASS_DESKTOP  },
Packit Service 8264ee
	{ "server",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_SERVER   },
Packit Service 8264ee
	{ "laptop",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_LAPTOP   },
Packit Service 8264ee
	{ "handset",  MAJOR_CLASS_COMPUTER, MINOR_CLASS_HANDHELD },
Packit Service 8264ee
	{ "tablet",   MAJOR_CLASS_COMPUTER, MINOR_CLASS_TABLET   },
Packit Service 8264ee
	{ }
Packit Service 8264ee
};
Packit Service 8264ee
Packit Service 8264ee
static void property_changed(GDBusProxy *proxy, const char *name,
Packit Service 8264ee
					DBusMessageIter *iter, void *user_data)
Packit Service 8264ee
{
Packit Service 8264ee
	if (g_str_equal(name, "PrettyHostname") == TRUE) {
Packit Service 8264ee
		if (iter == NULL) {
Packit Service 8264ee
			g_dbus_proxy_refresh_property(proxy, name);
Packit Service 8264ee
			return;
Packit Service 8264ee
		}
Packit Service 8264ee
Packit Service 8264ee
		if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
Packit Service 8264ee
			const char *str;
Packit Service 8264ee
Packit Service 8264ee
			dbus_message_iter_get_basic(iter, &str);
Packit Service 8264ee
Packit Service 8264ee
			DBG("pretty hostname: %s", str);
Packit Service 8264ee
Packit Service 8264ee
			g_free(pretty_hostname);
Packit Service 8264ee
			pretty_hostname = g_strdup(str);
Packit Service 8264ee
Packit Service 8264ee
			adapter_foreach(update_name, NULL);
Packit Service 8264ee
		}
Packit Service 8264ee
	} else if (g_str_equal(name, "StaticHostname") == TRUE) {
Packit Service 8264ee
		if (iter == NULL) {
Packit Service 8264ee
			g_dbus_proxy_refresh_property(proxy, name);
Packit Service 8264ee
			return;
Packit Service 8264ee
		}
Packit Service 8264ee
Packit Service 8264ee
		if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
Packit Service 8264ee
			const char *str;
Packit Service 8264ee
Packit Service 8264ee
			dbus_message_iter_get_basic(iter, &str);
Packit Service 8264ee
Packit Service 8264ee
			DBG("static hostname: %s", str);
Packit Service 8264ee
Packit Service 8264ee
			g_free(static_hostname);
Packit Service 8264ee
			static_hostname = g_strdup(str);
Packit Service 8264ee
Packit Service 8264ee
			adapter_foreach(update_name, NULL);
Packit Service 8264ee
		}
Packit Service 8264ee
	} else if (g_str_equal(name, "Chassis") == TRUE) {
Packit Service 8264ee
		if (iter == NULL) {
Packit Service 8264ee
			g_dbus_proxy_refresh_property(proxy, name);
Packit Service 8264ee
			return;
Packit Service 8264ee
		}
Packit Service 8264ee
Packit Service 8264ee
		if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
Packit Service 8264ee
			const char *str;
Packit Service 8264ee
			int i;
Packit Service 8264ee
Packit Service 8264ee
			dbus_message_iter_get_basic(iter, &str);
Packit Service 8264ee
Packit Service 8264ee
			DBG("chassis: %s", str);
Packit Service 8264ee
Packit Service 8264ee
			for (i = 0; chassis_table[i].chassis; i++) {
Packit Service 8264ee
				if (strcmp(chassis_table[i].chassis, str))
Packit Service 8264ee
					continue;
Packit Service 8264ee
Packit Service 8264ee
				major_class = chassis_table[i].major_class;
Packit Service 8264ee
				minor_class = chassis_table[i].minor_class;
Packit Service 8264ee
Packit Service 8264ee
				adapter_foreach(update_class, NULL);
Packit Service 8264ee
				break;
Packit Service 8264ee
			}
Packit Service 8264ee
		}
Packit Service 8264ee
	}
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static int hostname_probe(struct btd_adapter *adapter)
Packit Service 8264ee
{
Packit Service 8264ee
	DBG("");
Packit Service 8264ee
Packit Service 8264ee
	update_name(adapter, NULL);
Packit Service 8264ee
	update_class(adapter, NULL);
Packit Service 8264ee
Packit Service 8264ee
	return 0;
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static void hostname_remove(struct btd_adapter *adapter)
Packit Service 8264ee
{
Packit Service 8264ee
	DBG("");
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static struct btd_adapter_driver hostname_driver = {
Packit Service 8264ee
	.name	= "hostname",
Packit Service 8264ee
	.probe	= hostname_probe,
Packit Service 8264ee
	.remove	= hostname_remove,
Packit Service 8264ee
};
Packit Service 8264ee
Packit Service 8264ee
static void read_dmi_fallback(void)
Packit Service 8264ee
{
Packit Service 8264ee
	char *contents;
Packit Service 8264ee
	int i, type;
Packit Service 8264ee
	const char *str;
Packit Service 8264ee
Packit Service 8264ee
	if (g_file_get_contents("/sys/class/dmi/id/chassis_type",
Packit Service 8264ee
					&contents, NULL, NULL) == FALSE)
Packit Service 8264ee
		return;
Packit Service 8264ee
Packit Service 8264ee
	type = atoi(contents);
Packit Service 8264ee
	if (type < 0 || type > 0x1D)
Packit Service 8264ee
		return;
Packit Service 8264ee
Packit Service 8264ee
	g_free(contents);
Packit Service 8264ee
Packit Service 8264ee
	/* from systemd hostname chassis list */
Packit Service 8264ee
	switch (type) {
Packit Service 8264ee
	case 0x3:
Packit Service 8264ee
	case 0x4:
Packit Service 8264ee
	case 0x6:
Packit Service 8264ee
	case 0x7:
Packit Service 8264ee
		str = "desktop";
Packit Service 8264ee
		break;
Packit Service 8264ee
	case 0x8:
Packit Service 8264ee
	case 0x9:
Packit Service 8264ee
	case 0xA:
Packit Service 8264ee
	case 0xE:
Packit Service 8264ee
		str = "laptop";
Packit Service 8264ee
		break;
Packit Service 8264ee
	case 0xB:
Packit Service 8264ee
		str = "handset";
Packit Service 8264ee
		break;
Packit Service 8264ee
	case 0x11:
Packit Service 8264ee
	case 0x1C:
Packit Service 8264ee
		str = "server";
Packit Service 8264ee
		break;
Packit Service 8264ee
	default:
Packit Service 8264ee
		return;
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	DBG("chassis: %s", str);
Packit Service 8264ee
Packit Service 8264ee
	for (i = 0; chassis_table[i].chassis; i++) {
Packit Service 8264ee
		if (!strcmp(chassis_table[i].chassis, str)) {
Packit Service 8264ee
			major_class = chassis_table[i].major_class;
Packit Service 8264ee
			minor_class = chassis_table[i].minor_class;
Packit Service 8264ee
			break;
Packit Service 8264ee
		}
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	DBG("major: 0x%02x minor: 0x%02x", major_class, minor_class);
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static GDBusClient *hostname_client = NULL;
Packit Service 8264ee
static GDBusProxy *hostname_proxy = NULL;
Packit Service 8264ee
Packit Service 8264ee
static int hostname_init(void)
Packit Service 8264ee
{
Packit Service 8264ee
	DBusConnection *conn = btd_get_dbus_connection();
Packit Service 8264ee
	int err;
Packit Service 8264ee
Packit Service 8264ee
	read_dmi_fallback();
Packit Service 8264ee
Packit Service 8264ee
	hostname_client = g_dbus_client_new(conn, "org.freedesktop.hostname1",
Packit Service 8264ee
						"/org/freedesktop/hostname1");
Packit Service 8264ee
	if (!hostname_client)
Packit Service 8264ee
		return -EIO;
Packit Service 8264ee
Packit Service 8264ee
	hostname_proxy = g_dbus_proxy_new(hostname_client,
Packit Service 8264ee
						"/org/freedesktop/hostname1",
Packit Service 8264ee
						"org.freedesktop.hostname1");
Packit Service 8264ee
	if (!hostname_proxy) {
Packit Service 8264ee
		g_dbus_client_unref(hostname_client);
Packit Service 8264ee
		hostname_client = NULL;
Packit Service 8264ee
		return -EIO;
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	g_dbus_proxy_set_property_watch(hostname_proxy, property_changed, NULL);
Packit Service 8264ee
Packit Service 8264ee
	err = btd_register_adapter_driver(&hostname_driver);
Packit Service 8264ee
	if (err < 0) {
Packit Service 8264ee
		g_dbus_proxy_unref(hostname_proxy);
Packit Service 8264ee
		hostname_proxy = NULL;
Packit Service 8264ee
		g_dbus_client_unref(hostname_client);
Packit Service 8264ee
		hostname_client = NULL;
rpm-build a9ff8c
	} else {
rpm-build a9ff8c
		g_dbus_proxy_refresh_property(hostname_proxy, "PrettyHostname");
rpm-build a9ff8c
		g_dbus_proxy_refresh_property(hostname_proxy, "StaticHostname");
rpm-build a9ff8c
		g_dbus_proxy_refresh_property(hostname_proxy, "Chassis");
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	return err;
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
static void hostname_exit(void)
Packit Service 8264ee
{
Packit Service 8264ee
	btd_unregister_adapter_driver(&hostname_driver);
Packit Service 8264ee
Packit Service 8264ee
	if (hostname_proxy) {
Packit Service 8264ee
		g_dbus_proxy_unref(hostname_proxy);
Packit Service 8264ee
		hostname_proxy = NULL;
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	if (hostname_client) {
Packit Service 8264ee
		g_dbus_client_unref(hostname_client);
Packit Service 8264ee
		hostname_client = NULL;
Packit Service 8264ee
	}
Packit Service 8264ee
Packit Service 8264ee
	g_free(pretty_hostname);
Packit Service 8264ee
	g_free(static_hostname);
Packit Service 8264ee
}
Packit Service 8264ee
Packit Service 8264ee
BLUETOOTH_PLUGIN_DEFINE(hostname, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
Packit Service 8264ee
						hostname_init, hostname_exit)