/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 <string.h>

#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/dbus.h>
#include <connman/technology.h>
#include <connman/device.h>
#include <connman/inet.h>
#include <gdbus.h>

#define BLUEZ_SERVICE                   "org.bluez"
#define BLUEZ_PATH                      "/org/bluez"
#define BLUETOOTH_PAN_PANU              "00001115-0000-1000-8000-00805f9b34fb"
#define BLUETOOTH_PAN_NAP               "00001116-0000-1000-8000-00805f9b34fb"
#define BLUETOOTH_PAN_GN                "00001117-0000-1000-8000-00805f9b34fb"

#define BLUETOOTH_ADDR_LEN              6

static DBusConnection *connection;
static GDBusClient *client;
static GHashTable *devices;
static GHashTable *networks;
static bool bluetooth_tethering;

struct bluetooth_pan {
	struct connman_network *network;
	GDBusProxy *btdevice_proxy;
	GDBusProxy *btnetwork_proxy;
	const char *pan_role;
};

static void address2ident(const char *address, char *ident)
{
	int i;

	for (i = 0; i < BLUETOOTH_ADDR_LEN; i++) {
		ident[i * 2] = address[i * 3];
		ident[i * 2 + 1] = address[i * 3 + 1];
	}
	ident[BLUETOOTH_ADDR_LEN * 2] = '\0';
}

static const char *proxy_get_string(GDBusProxy *proxy, const char *property)
{
	DBusMessageIter iter;
	const char *str;

	if (!g_dbus_proxy_get_property(proxy, property, &iter))
		return NULL;
	dbus_message_iter_get_basic(&iter, &str);
	return str;
}

static bool proxy_get_bool(GDBusProxy *proxy, const char *property)
{
	DBusMessageIter iter;
	dbus_bool_t value;

	if (!g_dbus_proxy_get_property(proxy, property, &iter))
		return false;
	dbus_message_iter_get_basic(&iter, &value);
	return value;
}

static const char *proxy_get_role(GDBusProxy *proxy)
{
	DBusMessageIter iter, value;
	const char *pref = NULL;

	if (!proxy)
		return NULL;

        if (!g_dbus_proxy_get_property(proxy, "UUIDs", &iter))
		return NULL;

        dbus_message_iter_recurse(&iter, &value);
        while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) {
                const char *uuid;

		dbus_message_iter_get_basic(&value, &uuid);
		/*
		 * If a device offers more than one role, we prefer NAP,
		 * then GN, then PANU.
		 */
		if (!strcmp(uuid, BLUETOOTH_PAN_NAP))
			return "nap";
		if (!strcmp(uuid, BLUETOOTH_PAN_GN))
			pref = "gn";
		if (!strcmp(uuid, BLUETOOTH_PAN_PANU) && !pref)
			pref = "panu";

                dbus_message_iter_next(&value);
        }

	return pref;
}

static int bluetooth_pan_probe(struct connman_network *network)
{
	GHashTableIter iter;
	gpointer key, value;

	DBG("network %p", network);

	g_hash_table_iter_init(&iter, networks);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct bluetooth_pan *pan = value;

		if (network == pan->network)
			return 0;
	}

	return -EOPNOTSUPP;
}

static void pan_remove_nap(struct bluetooth_pan *pan)
{
	struct connman_device *device;
	struct connman_network *network = pan->network;

	DBG("network %p pan %p", pan->network, pan);

	if (!network)
		return;

	pan->network = NULL;
	connman_network_set_data(network, NULL);

	device = connman_network_get_device(network);
	if (device)
		connman_device_remove_network(device, network);

	connman_network_unref(network);
}

static void bluetooth_pan_remove(struct connman_network *network)
{
	struct bluetooth_pan *pan = connman_network_get_data(network);

	DBG("network %p pan %p", network, pan);

	connman_network_set_data(network, NULL);

	if (pan)
		pan_remove_nap(pan);
}

static bool pan_connect(struct bluetooth_pan *pan,
		const char *iface)
{
	int index;

	if (!iface) {
		if (!proxy_get_bool(pan->btnetwork_proxy, "Connected"))
			return false;
		iface = proxy_get_string(pan->btnetwork_proxy, "Interface");
	}

	if (!iface)
		return false;

	index = connman_inet_ifindex(iface);
	if (index < 0) {
		DBG("network %p invalid index %d", pan->network, index);
		return false;
	}

	connman_network_set_index(pan->network, index);
	connman_network_set_connected(pan->network, true);

	return true;
}

static void pan_connect_cb(DBusMessage *message, void *user_data)
{
	const char *path = user_data;
	const char *iface = NULL;
	struct bluetooth_pan *pan;
	DBusMessageIter iter;

	pan = g_hash_table_lookup(networks, path);
	if (!pan) {
		DBG("network already removed");
		return;
	}

	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
		const char *dbus_error = dbus_message_get_error_name(message);

		DBG("network %p %s", pan->network, dbus_error);

		if (strcmp(dbus_error,
				"org.bluez.Error.AlreadyConnected") != 0) {
			connman_network_set_error(pan->network,
				CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
			return;
		}
	} else {
		if (dbus_message_iter_init(message, &iter) &&
				dbus_message_iter_get_arg_type(&iter) ==
				DBUS_TYPE_STRING)
			dbus_message_iter_get_basic(&iter, &iface);
	}

	DBG("network %p interface %s", pan->network, iface);

	pan_connect(pan, iface);
}

static void pan_connect_append(DBusMessageIter *iter,
		void *user_data)
{
	const char *path = user_data;
	struct bluetooth_pan *pan;

	pan = g_hash_table_lookup(networks, path);
	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &pan->pan_role);
}

static int bluetooth_pan_connect(struct connman_network *network)
{
	struct bluetooth_pan *pan = connman_network_get_data(network);
	const char *path;

	DBG("network %p", network);

	if (!pan)
		return -EINVAL;

	path = g_dbus_proxy_get_path(pan->btnetwork_proxy);

	if (!g_dbus_proxy_method_call(pan->btnetwork_proxy, "Connect",
			pan_connect_append, pan_connect_cb,
			g_strdup(path), g_free))
		return -EIO;

	connman_network_set_associating(pan->network, true);

	return -EINPROGRESS;
}

static void pan_disconnect_cb(DBusMessage *message, void *user_data)
{
	const char *path = user_data;
	struct bluetooth_pan *pan;

	pan = g_hash_table_lookup(networks, path);
	if (!pan) {
		DBG("network already removed");
		return;
	}

	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
		const char *dbus_error = dbus_message_get_error_name(message);

		DBG("network %p %s", pan->network, dbus_error);
	}

	DBG("network %p", pan->network);

	connman_network_set_connected(pan->network, false);
}

static int bluetooth_pan_disconnect(struct connman_network *network, bool user_initiated)
{
	struct bluetooth_pan *pan = connman_network_get_data(network);
	const char *path;

	DBG("network %p", network);

	if (!pan)
		return -EINVAL;

	path = g_dbus_proxy_get_path(pan->btnetwork_proxy);

	if (!g_dbus_proxy_method_call(pan->btnetwork_proxy, "Disconnect",
			NULL, pan_disconnect_cb, g_strdup(path), g_free))
		return -EIO;

       return -EINPROGRESS;
}

static void btnetwork_property_change(GDBusProxy *proxy, const char *name,
		DBusMessageIter *iter, void *user_data)
{
	struct bluetooth_pan *pan;
	dbus_bool_t connected;
	bool proxy_connected, network_connected;

	if (strcmp(name, "Connected") != 0)
		return;

	pan = g_hash_table_lookup(networks, g_dbus_proxy_get_path(proxy));
	if (!pan || !pan->network)
		return;

	dbus_message_iter_get_basic(iter, &connected);
	proxy_connected = connected;

	network_connected = connman_network_get_connected(pan->network);

	DBG("network %p network connected %d proxy connected %d",
			pan->network, network_connected, proxy_connected);

       if (network_connected != proxy_connected)
               connman_network_set_connected(pan->network, proxy_connected);
}

static void pan_create_nap(struct bluetooth_pan *pan)
{
	struct connman_device *device;
	const char* role;

	role = proxy_get_role(pan->btdevice_proxy);
	if (!role) {
		pan_remove_nap(pan);
		return;
	}

	device = g_hash_table_lookup(devices,
			proxy_get_string(pan->btdevice_proxy, "Adapter"));

	if (!device || !connman_device_get_powered(device))
		return;

	if (!pan->network) {
		const char *address;
		char ident[BLUETOOTH_ADDR_LEN * 2 + 1];
		const char *name, *path;

		address = proxy_get_string(pan->btdevice_proxy, "Address");
		if (!address) {
			connman_warn("Bluetooth device address missing");
			return;
		}

		address2ident(address, ident);

		pan->network = connman_network_create(ident,
				CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN);

		name = proxy_get_string(pan->btdevice_proxy, "Alias");
		path = g_dbus_proxy_get_path(pan->btnetwork_proxy);

		DBG("network %p %s %s", pan->network, path, name);

		if (!pan->network) {
			connman_warn("Bluetooth network %s creation failed",
					path);
			return;
		}

		connman_network_set_data(pan->network, pan);
		connman_network_set_name(pan->network, name);
		connman_network_set_group(pan->network, ident);
	}

	pan->pan_role = role;
	connman_device_add_network(device, pan->network);

	if (pan_connect(pan, NULL))
		DBG("network %p already connected", pan->network);
}

static void btdevice_property_change(GDBusProxy *proxy, const char *name,
		DBusMessageIter *iter, void *user_data)
{
	struct bluetooth_pan *pan;
	const char *old_role = NULL;
	const char *new_role;

	if (strcmp(name, "UUIDs"))
		return;

	pan = g_hash_table_lookup(networks, g_dbus_proxy_get_path(proxy));
	if (!pan)
		return;

	if (pan->network &&
			connman_network_get_device(pan->network))
		old_role = pan->pan_role;
	new_role = proxy_get_role(pan->btdevice_proxy);

	DBG("network %p network role %s proxy role %s", pan->network, old_role,
			new_role);

	if (old_role && new_role && !strcmp(old_role, new_role))
		return;

	pan_create_nap(pan);
}

static void pan_free(gpointer data)
{
	struct bluetooth_pan *pan = data;

	if (pan->btnetwork_proxy) {
		g_dbus_proxy_unref(pan->btnetwork_proxy);
		pan->btnetwork_proxy = NULL;
	}

	if (pan->btdevice_proxy) {
		g_dbus_proxy_unref(pan->btdevice_proxy);
		pan->btdevice_proxy = NULL;
	}

	pan_remove_nap(pan);

	g_free(pan);
}

static void pan_create(GDBusProxy *network_proxy)
{
	const char *path = g_dbus_proxy_get_path(network_proxy);
	struct bluetooth_pan *pan;

	pan = g_try_new0(struct bluetooth_pan, 1);

	if (!pan) {
		connman_error("Out of memory creating PAN NAP");
		return;
	}

	g_hash_table_replace(networks, g_strdup(path), pan);

	pan->btnetwork_proxy = g_dbus_proxy_ref(network_proxy);
	pan->btdevice_proxy = g_dbus_proxy_new(client, path,
			"org.bluez.Device1");

	if (!pan->btdevice_proxy) {
		connman_error("Cannot create BT PAN watcher %s", path);
		g_hash_table_remove(networks, path);
		return;
	}

	g_dbus_proxy_set_property_watch(pan->btnetwork_proxy,
			btnetwork_property_change, NULL);

	g_dbus_proxy_set_property_watch(pan->btdevice_proxy,
			btdevice_property_change, NULL);

	DBG("pan %p %s role %s", pan, path, proxy_get_role(pan->btdevice_proxy));

	pan_create_nap(pan);
}

static struct connman_network_driver network_driver = {
	.name		= "bluetooth",
	.type           = CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN,
	.probe          = bluetooth_pan_probe,
	.remove         = bluetooth_pan_remove,
	.connect        = bluetooth_pan_connect,
	.disconnect     = bluetooth_pan_disconnect,
};

static void enable_device(struct connman_device *device, const char *path)
{
	GHashTableIter iter;
	gpointer key, value;

	DBG("device %p %s", device, path);
	connman_device_set_powered(device, true);

	g_hash_table_iter_init(&iter, networks);
	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct bluetooth_pan *pan = value;

		if (g_strcmp0(proxy_get_string(pan->btdevice_proxy, "Adapter"),
						path) == 0) {

			DBG("enable network %p", pan->network);
			pan_create_nap(pan);
		}
	}
}

static void device_enable_cb(const DBusError *error, void *user_data)
{
	char *path = user_data;
	struct connman_device *device;

	device = g_hash_table_lookup(devices, path);
	if (!device) {
		DBG("device already removed");
		goto out;
	}

	if (dbus_error_is_set(error)) {
		connman_warn("Bluetooth device %s not enabled %s",
				path, error->message);
		goto out;
	}

	enable_device(device, path);
out:
	g_free(path);
}

static int bluetooth_device_enable(struct connman_device *device)
{
	GDBusProxy *proxy;
	dbus_bool_t device_powered = TRUE;
	const char *path;

	if (!device)
		return -EINVAL;

	proxy = connman_device_get_data(device);
	if (!proxy)
		return -ENXIO;

	path = g_dbus_proxy_get_path(proxy);

	if (proxy_get_bool(proxy, "Powered")) {
		DBG("already enabled %p %s", device, path);
		return -EALREADY;
	}

	DBG("device %p %s", device, path);

	g_dbus_proxy_set_property_basic(proxy, "Powered",
			DBUS_TYPE_BOOLEAN, &device_powered,
			device_enable_cb, g_strdup(path), NULL);

	return -EINPROGRESS;
}

static void disable_device(struct connman_device *device, const char *path)
{
	GHashTableIter iter;
	gpointer key, value;

	DBG("device %p %s", device, path);
	connman_device_set_powered(device, false);

	g_hash_table_iter_init(&iter, networks);
	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct bluetooth_pan *pan = value;

		if (pan->network && connman_network_get_device(pan->network)
				== device) {
			DBG("disable network %p", pan->network);
			connman_device_remove_network(device, pan->network);
		}
	}
}

static void device_disable_cb(const DBusError *error, void *user_data)
{
	char *path = user_data;
	struct connman_device *device;

	device = g_hash_table_lookup(devices, path);
	if (!device) {
		DBG("device already removed");
		goto out;
	}

	if (dbus_error_is_set(error)) {
		connman_warn("Bluetooth device %s not disabled: %s",
				path, error->message);
		goto out;
	}

	disable_device(device, path);

out:
	g_free(path);
}

static int bluetooth_device_disable(struct connman_device *device)
{
	GDBusProxy *proxy;
	dbus_bool_t device_powered = FALSE;
	const char *path;

	if (!device)
		return -EINVAL;

	proxy = connman_device_get_data(device);
	if (!proxy)
		return -ENXIO;

	path = g_dbus_proxy_get_path(proxy);

	if (!proxy_get_bool(proxy, "Powered")) {
		DBG("already disabled %p %s", device, path);
		return -EALREADY;
	}

	DBG("device %p %s", device, path);

	g_dbus_proxy_set_property_basic(proxy, "Powered",
			DBUS_TYPE_BOOLEAN, &device_powered,
			device_disable_cb, g_strdup(path), NULL);

	return -EINPROGRESS;
}

static void adapter_property_change(GDBusProxy *proxy, const char *name,
		DBusMessageIter *iter, void *user_data)
{
	struct connman_device *device;
	const char *path;
	bool adapter_powered, device_powered;

	if (strcmp(name, "Powered") != 0)
		return;

	path = g_dbus_proxy_get_path(proxy);
	device = g_hash_table_lookup(devices, path);

	adapter_powered = proxy_get_bool(proxy, "Powered");
	device_powered = connman_device_get_powered(device);

	DBG("device %p %s device powered %d adapter powered %d", device, path,
			device_powered, adapter_powered);

	if (device_powered != adapter_powered) {
		if (adapter_powered)
			enable_device(device, path);
		else
			disable_device(device, path);
	}
}

static void device_free(gpointer data)
{
	struct connman_device *device = data;
	GDBusProxy *proxy = connman_device_get_data(device);

	connman_device_set_data(device, NULL);
	if (proxy)
		g_dbus_proxy_unref(proxy);

	connman_device_unregister(device);
	connman_device_unref(device);
}

struct tethering_info {
	struct connman_technology *technology;
	char *bridge;
	bool enable;
};

static void tethering_free(void *user_data)
{
	struct tethering_info *tethering = user_data;

	g_free(tethering->bridge);
	g_free(tethering);
}

static void tethering_create_cb(DBusMessage *message, void *user_data)
{
	struct tethering_info *tethering = user_data;

	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
		const char *dbus_error = dbus_message_get_error_name(message);

		DBG("%s tethering failed: %s",
				tethering->enable ? "enable" : "disable",
				dbus_error);
		return;
	}

	DBG("bridge %s %s", tethering->bridge, tethering->enable ?
			"enabled": "disabled");

	if (tethering->technology)
		connman_technology_tethering_notify(tethering->technology,
				tethering->enable);
}

static void tethering_append(DBusMessageIter *iter, void *user_data)
{
	struct tethering_info *tethering = user_data;
	const char *nap = "nap";

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &nap);
	if (tethering->enable)
		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
				&tethering->bridge);
}

static bool tethering_create(const char *path,
		struct connman_technology *technology, const char *bridge,
		bool enabled)
{
	struct tethering_info *tethering = g_new0(struct tethering_info, 1);
	GDBusProxy *proxy;
	const char *method;
	bool result;

	DBG("path %s bridge %s", path, bridge);

	if (!bridge)
		return -EINVAL;

	proxy = g_dbus_proxy_new(client, path, "org.bluez.NetworkServer1");
	if (!proxy)
		return false;

	tethering->technology = technology;
	tethering->bridge = g_strdup(bridge);
	tethering->enable = enabled;

	if (tethering->enable)
		method = "Register";
	else
		method = "Unregister";

	result = g_dbus_proxy_method_call(proxy, method, tethering_append,
			tethering_create_cb, tethering, tethering_free);

	g_dbus_proxy_unref(proxy);

	return result;
}

static void device_create(GDBusProxy *proxy)
{
	struct connman_device *device = NULL;
	const char *path = g_dbus_proxy_get_path(proxy);
	const char *address;
	char ident[BLUETOOTH_ADDR_LEN * 2 + 1];
	bool powered;

	address = proxy_get_string(proxy, "Address");
	if (!address)
		return;

	address2ident(address, ident);

	device = connman_device_create("bluetooth",
			CONNMAN_DEVICE_TYPE_BLUETOOTH);
	if (!device)
		return;

	connman_device_set_data(device, g_dbus_proxy_ref(proxy));
	connman_device_set_ident(device, ident);

	g_hash_table_replace(devices, g_strdup(path), device);

	DBG("device %p %s device powered %d adapter powered %d", device,
			path, connman_device_get_powered(device),
			proxy_get_bool(proxy, "Powered"));

	if (connman_device_register(device) < 0) {
		g_hash_table_remove(devices, device);
		return;
	}

	g_dbus_proxy_set_property_watch(proxy, adapter_property_change, NULL);

	powered = proxy_get_bool(proxy, "Powered");
	connman_device_set_powered(device, powered);

	if (proxy_get_role(proxy) && !bluetooth_tethering)
		tethering_create(path, NULL, NULL, false);
}

static void object_added(GDBusProxy *proxy, void *user_data)
{
	const char *interface;

	interface = g_dbus_proxy_get_interface(proxy);
	if (!interface) {
		connman_warn("Interface or proxy missing when adding "
							"bluetooth object");
		return;
	}

	if (strcmp(interface, "org.bluez.Adapter1") == 0) {
		DBG("%s %s", interface, g_dbus_proxy_get_path(proxy));
		device_create(proxy);
		return;
	}

	if (strcmp(interface, "org.bluez.Network1") == 0) {
		DBG("%s %s", interface, g_dbus_proxy_get_path(proxy));
		pan_create(proxy);
		return;
	}
}

static void object_removed(GDBusProxy *proxy, void *user_data)
{
	const char *interface, *path;

	interface = g_dbus_proxy_get_interface(proxy);
	if (!interface) {
		connman_warn("Interface or proxy missing when removing "
							"bluetooth object");
		return;
	}

	if (strcmp(interface, "org.bluez.Adapter1") == 0) {
		path = g_dbus_proxy_get_path(proxy);
		DBG("%s %s", interface, path);

		g_hash_table_remove(devices, path);
	}

	if (strcmp(interface, "org.bluez.Network1") == 0) {
		path = g_dbus_proxy_get_path(proxy);
		DBG("%s %s", interface, path);

		g_hash_table_remove(networks, path);
	}

}

static int bluetooth_device_probe(struct connman_device *device)
{
	GHashTableIter iter;
	gpointer key, value;

	g_hash_table_iter_init(&iter, devices);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct connman_device *known = value;

		if (device == known)
			return 0;
	}

	return -EOPNOTSUPP;
}

static void bluetooth_device_remove(struct connman_device *device)
{
	DBG("%p", device);
}

static struct connman_device_driver device_driver = {
	.name		= "bluetooth",
	.type		= CONNMAN_DEVICE_TYPE_BLUETOOTH,
	.probe          = bluetooth_device_probe,
	.remove         = bluetooth_device_remove,
	.enable         = bluetooth_device_enable,
	.disable        = bluetooth_device_disable,
};

static int bluetooth_tech_probe(struct connman_technology *technology)
{
	return 0;
}

static void bluetooth_tech_remove(struct connman_technology *technology)
{

}

static int bluetooth_tech_set_tethering(struct connman_technology *technology,
		const char *identifier, const char *passphrase,
		const char *bridge, bool enabled)
{
	GHashTableIter hash_iter;
	gpointer key, value;
	int i = 0;

	bluetooth_tethering = enabled;

	g_hash_table_iter_init(&hash_iter, devices);

	while (g_hash_table_iter_next(&hash_iter, &key, &value)) {
		const char *path = key;
		struct connman_device *device = value;

		DBG("device %p", device);

		if (tethering_create(path, technology, bridge, enabled)
				)
			i++;
	}

	DBG("%s %d device(s)", enabled ? "enabled" : "disabled", i);

	if (i == 0)
		return -ENODEV;

	return 0;
}

static struct connman_technology_driver tech_driver = {
	.name		= "bluetooth",
	.type		= CONNMAN_SERVICE_TYPE_BLUETOOTH,
	.probe          = bluetooth_tech_probe,
	.remove         = bluetooth_tech_remove,
	.set_tethering  = bluetooth_tech_set_tethering,
};

static int bluetooth_init(void)
{
	connection = connman_dbus_get_connection();
	if (!connection)
		goto out;

	if (connman_technology_driver_register(&tech_driver) < 0) {
		connman_warn("Failed to initialize technology for Bluez 5");
		goto out;
	}

	devices = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
			device_free);

	if (connman_device_driver_register(&device_driver) < 0) {
		connman_warn("Failed to initialize device driver for "
				BLUEZ_SERVICE);
		connman_technology_driver_unregister(&tech_driver);
		goto out;
	}

	if (connman_network_driver_register(&network_driver) < 0) {
		connman_technology_driver_unregister(&tech_driver);
		connman_device_driver_unregister(&device_driver);
		goto out;
	}

	networks = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
			pan_free);

	client = g_dbus_client_new(connection, BLUEZ_SERVICE, BLUEZ_PATH);
	if (!client) {
		connman_warn("Failed to initialize D-Bus client for "
				BLUEZ_SERVICE);
		goto out;
	}

	g_dbus_client_set_proxy_handlers(client, object_added, object_removed,
			NULL, NULL);

	return 0;

out:
	if (networks)
		g_hash_table_destroy(networks);

	if (devices)
		g_hash_table_destroy(devices);

	if (client)
		g_dbus_client_unref(client);

	if (connection)
		dbus_connection_unref(connection);

	return -EIO;
}

static void bluetooth_exit(void)
{
	/*
	 * We unset the disabling of the Bluetooth device when shutting down
	 * so that non-PAN BT connections are not affected.
	 */
	device_driver.disable = NULL;

	g_dbus_client_unref(client);

	connman_network_driver_unregister(&network_driver);
	g_hash_table_destroy(networks);

	connman_device_driver_unregister(&device_driver);
	g_hash_table_destroy(devices);

	connman_technology_driver_unregister(&tech_driver);
	dbus_connection_unref(connection);
}

CONNMAN_PLUGIN_DEFINE(bluetooth, "Bluetooth technology plugin", VERSION,
                CONNMAN_PLUGIN_PRIORITY_DEFAULT, bluetooth_init, bluetooth_exit)
