/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-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 <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ether.h>

#include <gdbus.h>

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

#define BLUEZ_SERVICE			"org.bluez"
#define BLUEZ_MANAGER_INTERFACE		BLUEZ_SERVICE ".Manager"
#define BLUEZ_ADAPTER_INTERFACE		BLUEZ_SERVICE ".Adapter"
#define BLUEZ_DEVICE_INTERFACE		BLUEZ_SERVICE ".Device"
#define BLUEZ_NETWORK_INTERFACE		BLUEZ_SERVICE ".Network"
#define BLUEZ_NETWORK_SERVER		BLUEZ_SERVICE ".NetworkServer"

#define LIST_ADAPTERS			"ListAdapters"
#define ADAPTER_ADDED			"AdapterAdded"
#define ADAPTER_REMOVED			"AdapterRemoved"
#define DEVICE_REMOVED			"DeviceRemoved"

#define PROPERTY_CHANGED		"PropertyChanged"
#define GET_PROPERTIES			"GetProperties"
#define SET_PROPERTY			"SetProperty"

#define CONNECT				"Connect"
#define DISCONNECT			"Disconnect"

#define REGISTER			"Register"
#define UNREGISTER			"Unregister"

#define UUID_NAP	"00001116-0000-1000-8000-00805f9b34fb"

#define TIMEOUT 60000

static DBusConnection *connection;

static GHashTable *bluetooth_devices = NULL;
static GHashTable *bluetooth_networks = NULL;
static GHashTable *pending_networks = NULL;

static int pan_probe(struct connman_network *network)
{
	GHashTableIter iter;
	gpointer key, val;

	g_hash_table_iter_init(&iter, bluetooth_networks);
	while (g_hash_table_iter_next(&iter, &key, &val)) {
		struct connman_network *known = val;

		if (network != known)
			continue;

		DBG("network %p", network);

		return 0;
	}

	return -EOPNOTSUPP;
}

static void pan_remove(struct connman_network *network)
{
	DBG("network %p", network);
}

static void connect_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_network *network;
	DBusMessage *reply;
	DBusError error;
	const char *interface = NULL;
	int index;

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (!network)
		return;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);

		goto err;
	}

	if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING,
					&interface, DBUS_TYPE_INVALID)) {
		if (dbus_error_is_set(&error)) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for connect");
		goto err;
	}

	if (!interface)
		goto err;

	DBG("interface %s", interface);

	index = connman_inet_ifindex(interface);

	connman_network_set_index(network, index);

	connman_network_set_connected(network, true);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	return;
err:

	connman_network_set_connected(network, false);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static int pan_connect(struct connman_network *network)
{
	const char *path = connman_network_get_string(network, "Path");
	const char *uuid = "nap";
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("network %p", network);

	if (!path)
		return -EINVAL;

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
					BLUEZ_NETWORK_INTERFACE, CONNECT);
	if (!message)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_append_args(message, DBUS_TYPE_STRING, &uuid,
							DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT * 10)) {
		connman_error("Failed to connect service");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	dbus_pending_call_set_notify(call, connect_reply, g_strdup(path),
			g_free);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static void disconnect_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_network *network;
	DBusMessage *reply;
	DBusError error;

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (!network)
		return;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID)) {
		if (dbus_error_is_set(&error)) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for disconnect");
		goto done;
	}

	connman_network_set_connected(network, false);

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	connman_network_unref(network);
}

static int pan_disconnect(struct connman_network *network, bool user_initiated)
{
	const char *path = connman_network_get_string(network, "Path");
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("network %p", network);

	if (!path)
		return -EINVAL;

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
					BLUEZ_NETWORK_INTERFACE, DISCONNECT);
	if (!message)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_append_args(message, DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to disconnect service");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	connman_network_ref(network);

	connman_network_set_associating(network, false);

	dbus_pending_call_set_notify(call, disconnect_reply, g_strdup(path),
			g_free);

	dbus_message_unref(message);

	return 0;
}

static struct connman_network_driver pan_driver = {
	.name		= "bluetooth_legacy-pan",
	.type		= CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN,
	.priority       = CONNMAN_NETWORK_PRIORITY_LOW,
	.probe		= pan_probe,
	.remove		= pan_remove,
	.connect	= pan_connect,
	.disconnect	= pan_disconnect,
};

static gboolean network_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct connman_network *network;
	DBusMessageIter iter, value;
	const char *key;

	DBG("path %s", path);

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (!network)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &value);

	if (g_str_equal(key, "Connected")) {
		dbus_bool_t connected;

		dbus_message_iter_get_basic(&value, &connected);

		if (connected)
			return TRUE;

		connman_network_set_associating(network, false);
		connman_network_set_connected(network, false);
	}

	return TRUE;
}

static void extract_properties(DBusMessage *reply, const char **parent,
						const char **address,
						const char **name,
						const char **alias,
						dbus_bool_t *powered,
						dbus_bool_t *scanning,
						DBusMessageIter *uuids,
						DBusMessageIter *networks)
{
	DBusMessageIter array, dict;

	if (!dbus_message_iter_init(reply, &array))
		return;

	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(&array, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		const char *key;

		dbus_message_iter_recurse(&dict, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (g_str_equal(key, "Adapter")) {
			if (parent)
				dbus_message_iter_get_basic(&value, parent);
		} else if (g_str_equal(key, "Address")) {
			if (address)
				dbus_message_iter_get_basic(&value, address);
		} else if (g_str_equal(key, "Name")) {
			if (name)
				dbus_message_iter_get_basic(&value, name);
		} else if (g_str_equal(key, "Alias")) {
			if (alias)
				dbus_message_iter_get_basic(&value, alias);
		} else if (g_str_equal(key, "Powered")) {
			if (powered)
				dbus_message_iter_get_basic(&value, powered);
		} else if (g_str_equal(key, "Discovering")) {
			if (scanning)
				dbus_message_iter_get_basic(&value, scanning);
		} else if (g_str_equal(key, "Devices")) {
			if (networks)
				memcpy(networks, &value, sizeof(value));
		} else if (g_str_equal(key, "UUIDs")) {
			if (uuids)
				memcpy(uuids, &value, sizeof(value));
		}

		dbus_message_iter_next(&dict);
	}
}

static dbus_bool_t has_pan(DBusMessageIter *array)
{
	DBusMessageIter value;

	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
		return FALSE;

	dbus_message_iter_recurse(array, &value);

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

		dbus_message_iter_get_basic(&value, &uuid);

		if (g_strcmp0(uuid, UUID_NAP) == 0)
			return TRUE;

		dbus_message_iter_next(&value);
	}

	return FALSE;
}

static void network_properties_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_device *device;
	struct connman_network *network;
	DBusMessage *reply;
	DBusMessageIter uuids;
	const char *parent = NULL, *address = NULL, *name = NULL;
	struct ether_addr addr;
	char ident[13];

	reply = dbus_pending_call_steal_reply(call);

	extract_properties(reply, &parent, &address, NULL, &name,
						NULL, NULL, &uuids, NULL);

	if (!parent)
		goto done;

	device = g_hash_table_lookup(bluetooth_devices, parent);
	if (!device)
		goto done;

	if (!address)
		goto done;

	ether_aton_r(address, &addr);

	snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
						addr.ether_addr_octet[0],
						addr.ether_addr_octet[1],
						addr.ether_addr_octet[2],
						addr.ether_addr_octet[3],
						addr.ether_addr_octet[4],
						addr.ether_addr_octet[5]);

	if (!has_pan(&uuids))
		goto done;

	network = connman_device_get_network(device, ident);
	if (network)
		goto done;

	network = connman_network_create(ident,
					CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN);
	if (!network)
		goto done;

	connman_network_set_string(network, "Path", path);

	connman_network_set_name(network, name);

	g_hash_table_replace(bluetooth_networks, g_strdup(path), network);

	connman_device_add_network(device, network);

	connman_network_set_group(network, ident);

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static void add_network(const char *path)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("path %s", path);

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
				BLUEZ_DEVICE_INTERFACE, GET_PROPERTIES);
	if (!message)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to get network properties for %s", path);
		goto done;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	dbus_pending_call_set_notify(call, network_properties_reply,
						g_strdup(path), g_free);

done:
	dbus_message_unref(message);
}

static void check_networks(DBusMessageIter *array)
{
	DBusMessageIter value;

	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(array, &value);

	while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
		const char *path;

		dbus_message_iter_get_basic(&value, &path);

		add_network(path);

		dbus_message_iter_next(&value);
	}
}

static void check_pending_networks(const char *adapter)
{
	GSList *networks, *list;

	networks = g_hash_table_lookup(pending_networks, adapter);
	if (!networks)
		return;

	for (list = networks; list; list = list->next) {
		char *path = list->data;

		add_network(path);
	}

	g_hash_table_remove(pending_networks, adapter);
}

static gboolean adapter_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct connman_device *device;
	DBusMessageIter iter, value;
	const char *key;

	DBG("path %s", path);

	device = g_hash_table_lookup(bluetooth_devices, path);
	if (!device)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &value);

	if (g_str_equal(key, "Powered")) {
		dbus_bool_t val;

		dbus_message_iter_get_basic(&value, &val);
		connman_device_set_powered(device, val);
		if (val)
			check_pending_networks(path);
	} else if (g_str_equal(key, "Discovering")) {
		dbus_bool_t val;

		dbus_message_iter_get_basic(&value, &val);
		connman_device_set_scanning(device,
				CONNMAN_SERVICE_TYPE_BLUETOOTH, val);
	} else if (g_str_equal(key, "Devices")) {
		check_networks(&value);
	}

	return TRUE;
}

static gboolean device_removed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *network_path;
	struct connman_network *network;
	struct connman_device *device;
	DBusMessageIter iter;

	DBG("");

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &network_path);

	network = g_hash_table_lookup(bluetooth_networks, network_path);
	if (!network)
		return TRUE;

	device = connman_network_get_device(network);
	if (!device)
		return TRUE;

	g_hash_table_remove(bluetooth_networks, network_path);

	return TRUE;
}

static gboolean device_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	DBusMessageIter iter, value;
	const char *key;

	DBG("path %s", path);

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &value);

	DBG("key %s", key);

	if (g_str_equal(key, "UUIDs"))
		add_network(path);

	return TRUE;
}

static void remove_device_networks(struct connman_device *device)
{
	GHashTableIter iter;
	gpointer key, value;
	GSList *key_list = NULL;
	GSList *list;

	if (!bluetooth_networks)
		return;

	g_hash_table_iter_init(&iter, bluetooth_networks);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct connman_network *network = value;

		if (connman_network_get_device(network) != device)
			continue;

		key_list = g_slist_prepend(key_list, key);
	}

	for (list = key_list; list; list = list->next) {
		const char *network_path = list->data;

		g_hash_table_remove(bluetooth_networks, network_path);
	}

	g_slist_free(key_list);
}

static void add_pending_networks(const char *adapter, DBusMessageIter *array)
{
	DBusMessageIter value;
	GSList *list = NULL;

	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(array, &value);

	while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
		const char *path;

		dbus_message_iter_get_basic(&value, &path);

		list = g_slist_prepend(list, g_strdup(path));

		dbus_message_iter_next(&value);
	}

	if (!list)
		return;

	g_hash_table_replace(pending_networks, g_strdup(adapter), list);
}

static void adapter_properties_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_device *device;
	DBusMessage *reply;
	DBusMessageIter networks;
	const char *address = NULL, *name = NULL;
	dbus_bool_t powered = FALSE, scanning = FALSE;
	struct ether_addr addr;
	char ident[13];

	DBG("path %s", path);

	reply = dbus_pending_call_steal_reply(call);

	if (!path)
		goto done;

	extract_properties(reply, NULL, &address, &name, NULL,
					&powered, &scanning, NULL, &networks);

	if (!address)
		goto done;

	if (g_strcmp0(address, "00:00:00:00:00:00") == 0)
		goto done;

	device = g_hash_table_lookup(bluetooth_devices, path);
	if (device)
		goto update;

	ether_aton_r(address, &addr);

	snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
						addr.ether_addr_octet[0],
						addr.ether_addr_octet[1],
						addr.ether_addr_octet[2],
						addr.ether_addr_octet[3],
						addr.ether_addr_octet[4],
						addr.ether_addr_octet[5]);

	device = connman_device_create("bluetooth_legacy",
			CONNMAN_DEVICE_TYPE_BLUETOOTH);
	if (!device)
		goto done;

	g_hash_table_insert(bluetooth_devices, g_strdup(path), device);

	connman_device_set_ident(device, ident);

	connman_device_set_string(device, "Path", path);

	if (connman_device_register(device) < 0) {
		connman_device_unref(device);
		g_hash_table_remove(bluetooth_devices, path);
		goto done;
	}

update:
	connman_device_set_string(device, "Address", address);
	connman_device_set_string(device, "Name", name);
	connman_device_set_string(device, "Path", path);

	connman_device_set_powered(device, powered);
	connman_device_set_scanning(device,
			CONNMAN_SERVICE_TYPE_BLUETOOTH, scanning);

	if (!powered) {
		remove_device_networks(device);
		add_pending_networks(path, &networks);
	} else
		check_networks(&networks);

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static void add_adapter(DBusConnection *conn, const char *path)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("path %s", path);

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
				BLUEZ_ADAPTER_INTERFACE, GET_PROPERTIES);
	if (!message)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
		connman_error("Failed to get adapter properties for %s", path);
		goto done;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	dbus_pending_call_set_notify(call, adapter_properties_reply,
						g_strdup(path), g_free);

done:
	dbus_message_unref(message);
}

static gboolean adapter_added(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path;

	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
				DBUS_TYPE_INVALID);
	add_adapter(conn, path);
	return TRUE;
}

static void remove_adapter(DBusConnection *conn, const char *path)
{
	DBG("path %s", path);

	g_hash_table_remove(bluetooth_devices, path);
	g_hash_table_remove(pending_networks, path);
}

static gboolean adapter_removed(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path;

	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
				DBUS_TYPE_INVALID);
	remove_adapter(conn, path);
	return TRUE;
}

static void list_adapters_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;
	char **adapters;
	int i, num_adapters;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (!dbus_message_get_args(reply, &error, DBUS_TYPE_ARRAY,
			DBUS_TYPE_OBJECT_PATH, &adapters,
			&num_adapters, DBUS_TYPE_INVALID)) {
		if (dbus_error_is_set(&error)) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for adapter list");
		goto done;
	}

	for (i = 0; i < num_adapters; i++)
		add_adapter(connection, adapters[i]);

	g_strfreev(adapters);

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static void unregister_device(gpointer data)
{
	struct connman_device *device = data;

	DBG("");

	remove_device_networks(device);

	connman_device_unregister(device);
	connman_device_unref(device);
}

static void remove_network(gpointer data)
{
	struct connman_network *network = data;
	struct connman_device *device;

	DBG("network %p", network);

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

	connman_network_unref(network);
}

static void remove_pending_networks(gpointer data)
{
	GSList *list = data;

	g_slist_free_full(list, g_free);
}

static void bluetooth_connect(DBusConnection *conn, void *user_data)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("connection %p", conn);

	bluetooth_devices = g_hash_table_new_full(g_str_hash, g_str_equal,
						g_free, unregister_device);

	bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
						g_free, remove_network);

	pending_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
					g_free, remove_pending_networks);

	message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
				BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS);
	if (!message)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
		connman_error("Failed to get Bluetooth adapters");
		goto done;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	dbus_pending_call_set_notify(call, list_adapters_reply, NULL, NULL);

done:
	dbus_message_unref(message);
}

static void bluetooth_disconnect(DBusConnection *conn, void *user_data)
{
	DBG("connection %p", conn);

	if (!bluetooth_devices)
		return;

	g_hash_table_destroy(bluetooth_networks);
	bluetooth_networks = NULL;
	g_hash_table_destroy(bluetooth_devices);
	bluetooth_devices = NULL;
	g_hash_table_destroy(pending_networks);
	pending_networks = NULL;
}

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

	DBG("device %p", device);

	if (!bluetooth_devices)
		return -ENOTSUP;

	g_hash_table_iter_init(&iter, bluetooth_devices);

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

		if (device == device_pan)
			return 0;
	}

	return -ENOTSUP;
}

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

static void powered_reply(DBusPendingCall *call, void *user_data)
{
	DBusError error;
	DBusMessage *reply;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		dbus_message_unref(reply);
		dbus_pending_call_unref(call);
		return;
	}

	dbus_message_unref(reply);
	dbus_pending_call_unref(call);

	add_adapter(connection, user_data);
}

static int change_powered(DBusConnection *conn, const char *path,
							dbus_bool_t powered)
{
	DBusMessage *message;
	DBusMessageIter iter;
	DBusPendingCall *call;

	DBG("");

	if (!path)
		return -EINVAL;

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
					BLUEZ_ADAPTER_INTERFACE, SET_PROPERTY);
	if (!message)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_iter_init_append(message, &iter);
	connman_dbus_property_append_basic(&iter, "Powered",
						DBUS_TYPE_BOOLEAN, &powered);

	if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
		connman_error("Failed to change Powered property");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	dbus_pending_call_set_notify(call, powered_reply,
					g_strdup(path), g_free);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static int bluetooth_enable(struct connman_device *device)
{
	const char *path = connman_device_get_string(device, "Path");

	DBG("device %p", device);

	return change_powered(connection, path, TRUE);
}

static int bluetooth_disable(struct connman_device *device)
{
	const char *path = connman_device_get_string(device, "Path");

	DBG("device %p", device);

	return change_powered(connection, path, FALSE);
}

static struct connman_device_driver bluetooth_driver = {
	.name		= "bluetooth_legacy",
	.type		= CONNMAN_DEVICE_TYPE_BLUETOOTH,
	.probe		= bluetooth_probe,
	.remove		= bluetooth_remove,
	.enable		= bluetooth_enable,
	.disable	= bluetooth_disable,
};

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

static void tech_remove(struct connman_technology *technology)
{
}

static void server_register_reply(DBusPendingCall *call, void *user_data)
{
	struct connman_technology *technology = user_data;
	DBusError error;
	DBusMessage *reply;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		dbus_message_unref(reply);
		dbus_pending_call_unref(call);
		return;
	}

	dbus_message_unref(reply);
	dbus_pending_call_unref(call);

	connman_technology_tethering_notify(technology, true);
}

static void server_unregister_reply(DBusPendingCall *call, void *user_data)
{
	struct connman_technology *technology = user_data;
	DBusError error;
	DBusMessage *reply;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		dbus_message_unref(reply);
		dbus_pending_call_unref(call);
		return;
	}

	dbus_message_unref(reply);
	dbus_pending_call_unref(call);

	connman_technology_tethering_notify(technology, false);
}


static void server_register(const char *path, const char *uuid,
				struct connman_technology *technology,
				const char *bridge, bool enabled)
{
	DBusMessage *message;
	DBusPendingCall *call;
	char *command;

	DBG("path %s enabled %d", path, enabled);

	command = enabled ? REGISTER : UNREGISTER;

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
					BLUEZ_NETWORK_SERVER, command);
	if (!message)
		return;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_append_args(message, DBUS_TYPE_STRING, &uuid,
							DBUS_TYPE_INVALID);

	if (enabled)
		dbus_message_append_args(message, DBUS_TYPE_STRING, &bridge,
							DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to enable PAN server");
		dbus_message_unref(message);
		return;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return;
	}

	if (enabled)
		dbus_pending_call_set_notify(call, server_register_reply,
						technology, NULL);
	else
		dbus_pending_call_set_notify(call, server_unregister_reply,
						technology, NULL);

	dbus_message_unref(message);
}

struct tethering_info {
	struct connman_technology *technology;
	const char *bridge;
};

static void enable_nap(gpointer key, gpointer value, gpointer user_data)
{
	struct tethering_info *info = user_data;
	struct connman_device *device = value;
	const char *path;

	DBG("");

	path = connman_device_get_string(device, "Path");

	server_register(path, "nap", info->technology, info->bridge, true);
}

static void disable_nap(gpointer key, gpointer value, gpointer user_data)
{
	struct tethering_info *info = user_data;
	struct connman_device *device = value;
	const char *path;

	DBG("");

	path = connman_device_get_string(device, "Path");

	server_register(path, "nap", info->technology, info->bridge, false);
}

static int tech_set_tethering(struct connman_technology *technology,
				const char *identifier, const char *passphrase,
				const char *bridge, bool enabled)
{
	struct tethering_info info = {
		.technology	= technology,
		.bridge		= bridge,
	};

	DBG("bridge %s", bridge);

	if (!bluetooth_devices)
		return -ENOTCONN;

	if (enabled)
		g_hash_table_foreach(bluetooth_devices, enable_nap, &info);
	else
		g_hash_table_foreach(bluetooth_devices, disable_nap, &info);

	return 0;
}

static struct connman_technology_driver tech_driver = {
	.name		= "bluetooth_legacy",
	.type		= CONNMAN_SERVICE_TYPE_BLUETOOTH,
	.priority       = -10,
	.probe		= tech_probe,
	.remove		= tech_remove,
	.set_tethering	= tech_set_tethering,
};

static guint watch;
static guint added_watch;
static guint removed_watch;
static guint adapter_watch;
static guint device_watch;
static guint device_removed_watch;
static guint network_watch;

static int bluetooth_init(void)
{
	int err;

	connection = connman_dbus_get_connection();
	if (!connection)
		return -EIO;

	watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE,
			bluetooth_connect, bluetooth_disconnect, NULL, NULL);

	added_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
						BLUEZ_MANAGER_INTERFACE,
						ADAPTER_ADDED, adapter_added,
						NULL, NULL);

	removed_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
						BLUEZ_MANAGER_INTERFACE,
						ADAPTER_REMOVED, adapter_removed,
						NULL, NULL);

	adapter_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
						NULL, BLUEZ_ADAPTER_INTERFACE,
						PROPERTY_CHANGED, adapter_changed,
						NULL, NULL);

	device_removed_watch = g_dbus_add_signal_watch(connection,
						BLUEZ_SERVICE, NULL,
						BLUEZ_ADAPTER_INTERFACE,
						DEVICE_REMOVED, device_removed,
						NULL, NULL);

	device_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
						BLUEZ_DEVICE_INTERFACE,
						PROPERTY_CHANGED, device_changed,
						NULL, NULL);

	network_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
						NULL, BLUEZ_NETWORK_INTERFACE,
						PROPERTY_CHANGED, network_changed,
						NULL, NULL);

	if (watch == 0 || added_watch == 0 || removed_watch == 0
			|| adapter_watch == 0 || network_watch == 0
				|| device_watch == 0
					|| device_removed_watch == 0) {
		err = -EIO;
		goto remove;
	}

	err = connman_network_driver_register(&pan_driver);
	if (err < 0)
		goto remove;

	err = connman_device_driver_register(&bluetooth_driver);
	if (err < 0) {
		connman_network_driver_unregister(&pan_driver);
		goto remove;
	}

	err = connman_technology_driver_register(&tech_driver);
	if (err < 0) {
		connman_device_driver_unregister(&bluetooth_driver);
		connman_network_driver_unregister(&pan_driver);
		goto remove;
	}

	return 0;

remove:
	g_dbus_remove_watch(connection, watch);
	g_dbus_remove_watch(connection, added_watch);
	g_dbus_remove_watch(connection, removed_watch);
	g_dbus_remove_watch(connection, adapter_watch);
	g_dbus_remove_watch(connection, device_removed_watch);
	g_dbus_remove_watch(connection, device_watch);
	g_dbus_remove_watch(connection, network_watch);

	dbus_connection_unref(connection);

	return err;
}

static void bluetooth_exit(void)
{
	g_dbus_remove_watch(connection, watch);
	g_dbus_remove_watch(connection, added_watch);
	g_dbus_remove_watch(connection, removed_watch);
	g_dbus_remove_watch(connection, adapter_watch);
	g_dbus_remove_watch(connection, device_removed_watch);
	g_dbus_remove_watch(connection, device_watch);
	g_dbus_remove_watch(connection, network_watch);

	/*
	 * We unset the disabling of the Bluetooth device when shutting down
	 * so that non-PAN BT connections are not affected.
	 */
	bluetooth_driver.disable = NULL;

	bluetooth_disconnect(connection, NULL);

	connman_technology_driver_unregister(&tech_driver);

	connman_device_driver_unregister(&bluetooth_driver);
	connman_network_driver_unregister(&pan_driver);

	dbus_connection_unref(connection);
}

CONNMAN_PLUGIN_DEFINE(bluetooth_legacy, "Bluetooth technology plugin (legacy)",
		VERSION, CONNMAN_PLUGIN_PRIORITY_LOW,
		bluetooth_init, bluetooth_exit)
