/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  Nokia Corporation
 *  Copyright (C) 2011  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 <stdbool.h>
#include <errno.h>
#include <gdbus/gdbus.h>
#include <glib.h>
#include <stdlib.h>

#include "lib/uuid.h"
#include "src/plugin.h"
#include "src/dbus-common.h"
#include "attrib/att.h"
#include "src/adapter.h"
#include "src/device.h"
#include "attrib/att-database.h"
#include "src/log.h"
#include "attrib/gatt-service.h"
#include "attrib/gattrib.h"
#include "src/attrib-server.h"
#include "attrib/gatt.h"
#include "src/profile.h"
#include "src/error.h"
#include "src/textfile.h"
#include "src/attio.h"

#define PHONE_ALERT_STATUS_SVC_UUID	0x180E
#define ALERT_NOTIF_SVC_UUID		0x1811

#define ALERT_STATUS_CHR_UUID		0x2A3F
#define RINGER_CP_CHR_UUID		0x2A40
#define RINGER_SETTING_CHR_UUID		0x2A41

#define ALERT_NOTIF_CP_CHR_UUID		0x2A44
#define UNREAD_ALERT_CHR_UUID		0x2A45
#define NEW_ALERT_CHR_UUID		0x2A46
#define SUPP_NEW_ALERT_CAT_CHR_UUID	0x2A47
#define SUPP_UNREAD_ALERT_CAT_CHR_UUID	0x2A48

#define ALERT_OBJECT_PATH		"/org/bluez"
#define ALERT_INTERFACE			"org.bluez.Alert1"
#define ALERT_AGENT_INTERFACE		"org.bluez.AlertAgent1"

/* Maximum length for "Text String Information" */
#define NEW_ALERT_MAX_INFO_SIZE		18
/* Maximum length for New Alert Characteristic Value */
#define NEW_ALERT_CHR_MAX_VALUE_SIZE	(NEW_ALERT_MAX_INFO_SIZE + 2)

enum {
	ENABLE_NEW_INCOMING,
	ENABLE_UNREAD_CAT,
	DISABLE_NEW_INCOMING,
	DISABLE_UNREAD_CAT,
	NOTIFY_NEW_INCOMING,
	NOTIFY_UNREAD_CAT,
};

enum {
	RINGER_SILENT_MODE = 1,
	RINGER_MUTE_ONCE,
	RINGER_CANCEL_SILENT_MODE,
};

/* Ringer Setting characteristic values */
enum {
	RINGER_SILENT,
	RINGER_NORMAL,
};

enum notify_type {
	NOTIFY_RINGER_SETTING = 0,
	NOTIFY_ALERT_STATUS,
	NOTIFY_NEW_ALERT,
	NOTIFY_UNREAD_ALERT,
	NOTIFY_SIZE,
};

struct alert_data {
	const char *category;
	char *srv;
	char *path;
	guint watcher;
};

struct alert_adapter {
	struct btd_adapter *adapter;
	uint16_t supp_new_alert_cat_handle;
	uint16_t supp_unread_alert_cat_handle;
	uint16_t hnd_ccc[NOTIFY_SIZE];
	uint16_t hnd_value[NOTIFY_SIZE];
};

struct notify_data {
	struct alert_adapter *al_adapter;
	enum notify_type type;
	uint8_t *value;
	size_t len;
};

struct notify_callback {
	struct notify_data *notify_data;
	struct btd_device *device;
	guint id;
};

static GSList *registered_alerts = NULL;
static GSList *alert_adapters = NULL;
static uint8_t ringer_setting = RINGER_NORMAL;
static uint8_t alert_status = 0;

static const char * const anp_categories[] = {
	"simple",
	"email",
	"news",
	"call",
	"missed-call",
	"sms-mms",
	"voice-mail",
	"schedule",
	"high-priority",
	"instant-message",
};

static const char * const pasp_categories[] = {
	"ringer",
	"vibrate",
	"display",
};

static int adapter_cmp(gconstpointer a, gconstpointer b)
{
	const struct alert_adapter *al_adapter = a;
	const struct btd_adapter *adapter = b;

	return al_adapter->adapter == adapter ? 0 : -1;
}

static struct alert_adapter *find_alert_adapter(struct btd_adapter *adapter)
{
	GSList *l = g_slist_find_custom(alert_adapters, adapter, adapter_cmp);

	return l ? l->data : NULL;
}

static void alert_data_destroy(gpointer user_data)
{
	struct alert_data *alert = user_data;

	if (alert->watcher)
		g_dbus_remove_watch(btd_get_dbus_connection(), alert->watcher);

	g_free(alert->srv);
	g_free(alert->path);
	g_free(alert);
}

static void alert_release(gpointer user_data)
{
	struct alert_data *alert = user_data;
	DBusMessage *msg;

	msg = dbus_message_new_method_call(alert->srv, alert->path,
							ALERT_AGENT_INTERFACE,
							"Release");
	if (msg)
		g_dbus_send_message(btd_get_dbus_connection(), msg);

	alert_data_destroy(alert);
}

static void alert_destroy(gpointer user_data)
{
	DBG("");

	g_slist_free_full(registered_alerts, alert_release);
	registered_alerts = NULL;
}

static const char *valid_category(const char *category)
{
	unsigned i;

	for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
		if (g_str_equal(anp_categories[i], category))
			return anp_categories[i];
	}

	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
		if (g_str_equal(pasp_categories[i], category))
			return pasp_categories[i];
	}

	return NULL;
}

static struct alert_data *get_alert_data_by_category(const char *category)
{
	GSList *l;
	struct alert_data *alert;

	for (l = registered_alerts; l; l = g_slist_next(l)) {
		alert = l->data;
		if (g_str_equal(alert->category, category))
			return alert;
	}

	return NULL;
}

static gboolean registered_category(const char *category)
{
	struct alert_data *alert;

	alert = get_alert_data_by_category(category);
	if (alert)
		return TRUE;

	return FALSE;
}

static gboolean pasp_category(const char *category)
{
	unsigned i;

	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++)
		if (g_str_equal(category, pasp_categories[i]))
			return TRUE;

	return FALSE;
}

static gboolean valid_description(const char *category,
						const char *description)
{
	if (!pasp_category(category)) {
		if (strlen(description) >= NEW_ALERT_MAX_INFO_SIZE)
			return FALSE;

		return TRUE;
	}

	if (g_str_equal(description, "active") ||
					g_str_equal(description, "not active"))
		return TRUE;

	if (g_str_equal(category, "ringer"))
		if (g_str_equal(description, "enabled") ||
					g_str_equal(description, "disabled"))
			return TRUE;

	return FALSE;
}

static gboolean valid_count(const char *category, uint16_t count)
{
	if (!pasp_category(category) && count > 0 && count <= 255)
		return TRUE;

	if (pasp_category(category) && count == 1)
		return TRUE;

	return FALSE;
}

static void update_supported_categories(gpointer data, gpointer user_data)
{
	struct alert_adapter *al_adapter = data;
	struct btd_adapter *adapter = al_adapter->adapter;
	uint8_t value[2];
	unsigned int i;

	memset(value, 0, sizeof(value));

	for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
		if (registered_category(anp_categories[i]))
			hci_set_bit(i, value);
	}

	attrib_db_update(adapter, al_adapter->supp_new_alert_cat_handle, NULL,
						value, sizeof(value), NULL);

	/* FIXME: For now report all registered categories as supporting unread
	 * status, until it is known which ones should be supported */
	attrib_db_update(adapter, al_adapter->supp_unread_alert_cat_handle,
					NULL, value, sizeof(value), NULL);
}

static void watcher_disconnect(DBusConnection *conn, void *user_data)
{
	struct alert_data *alert = user_data;

	DBG("Category %s was disconnected", alert->category);

	registered_alerts = g_slist_remove(registered_alerts, alert);
	alert_data_destroy(alert);

	g_slist_foreach(alert_adapters, update_supported_categories, NULL);
}

static gboolean is_notifiable_device(struct btd_device *device, uint16_t ccc)
{
	char *filename;
	GKeyFile *key_file;
	char handle[6];
	char *str;
	uint16_t val;
	gboolean result;

	sprintf(handle, "%hu", ccc);

	filename = btd_device_get_storage_path(device, "ccc");
	if (!filename) {
		warn("Unable to get ccc storage path for device");
		return FALSE;
	}

	key_file = g_key_file_new();
	g_key_file_load_from_file(key_file, filename, 0, NULL);

	str = g_key_file_get_string(key_file, handle, "Value", NULL);
	if (!str) {
		result = FALSE;
		goto end;
	}

	val = strtol(str, NULL, 16);
	if (!(val & 0x0001)) {
		result = FALSE;
		goto end;
	}

	result = TRUE;
end:
	g_free(str);
	g_free(filename);
	g_key_file_free(key_file);

	return result;
}

static void destroy_notify_callback(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct notify_callback *cb = user_data;

	DBG("status=%#x", status);

	btd_device_remove_attio_callback(cb->device, cb->id);
	btd_device_unref(cb->device);
	g_free(cb->notify_data->value);
	g_free(cb->notify_data);
	g_free(cb);
}

static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
	struct notify_callback *cb = user_data;
	struct notify_data *nd = cb->notify_data;
	enum notify_type type = nd->type;
	struct alert_adapter *al_adapter = nd->al_adapter;
	size_t len;
	uint8_t *pdu = g_attrib_get_buffer(attrib, &len);


	switch (type) {
	case NOTIFY_RINGER_SETTING:
		len = enc_notification(al_adapter->hnd_value[type],
				&ringer_setting, sizeof(ringer_setting),
				pdu, len);
		break;
	case NOTIFY_ALERT_STATUS:
		len = enc_notification(al_adapter->hnd_value[type],
				&alert_status, sizeof(alert_status),
				pdu, len);
		break;
	case NOTIFY_NEW_ALERT:
	case NOTIFY_UNREAD_ALERT:
		len = enc_notification(al_adapter->hnd_value[type],
					nd->value, nd->len, pdu, len);
		break;
	default:
		DBG("Unknown type, could not send notification");
		goto end;
	}

	DBG("Send notification for handle: 0x%04x, ccc: 0x%04x",
					al_adapter->hnd_value[type],
					al_adapter->hnd_ccc[type]);

	g_attrib_send(attrib, 0, pdu, len, destroy_notify_callback, cb, NULL);

	return;

end:
	btd_device_remove_attio_callback(cb->device, cb->id);
	btd_device_unref(cb->device);
	g_free(cb->notify_data->value);
	g_free(cb->notify_data);
	g_free(cb);
}

static void filter_devices_notify(struct btd_device *device, void *user_data)
{
	struct notify_data *notify_data = user_data;
	struct alert_adapter *al_adapter = notify_data->al_adapter;
	enum notify_type type = notify_data->type;
	struct notify_callback *cb;

	if (!is_notifiable_device(device, al_adapter->hnd_ccc[type]))
		return;

	cb = g_new0(struct notify_callback, 1);
	cb->notify_data = notify_data;
	cb->device = btd_device_ref(device);
	cb->id = btd_device_add_attio_callback(device,
						attio_connected_cb, NULL, cb);
}

static void notify_devices(struct alert_adapter *al_adapter,
			enum notify_type type, uint8_t *value, size_t len)
{
	struct notify_data *notify_data;

	notify_data = g_new0(struct notify_data, 1);
	notify_data->al_adapter = al_adapter;
	notify_data->type = type;
	notify_data->value = g_memdup(value, len);
	notify_data->len = len;

	btd_adapter_for_each_device(al_adapter->adapter, filter_devices_notify,
					notify_data);
}

static void pasp_notification(enum notify_type type)
{
	GSList *it;
	struct alert_adapter *al_adapter;

	for (it = alert_adapters; it; it = g_slist_next(it)) {
		al_adapter = it->data;

		notify_devices(al_adapter, type, NULL, 0);
	}
}

static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	const char *sender = dbus_message_get_sender(msg);
	char *path;
	const char *category;
	const char *c;
	struct alert_data *alert;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &c,
			DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	category = valid_category(c);
	if (!category) {
		DBG("Invalid category: %s", c);
		return btd_error_invalid_args(msg);
	}

	if (registered_category(category)) {
		DBG("Category %s already registered", category);
		return dbus_message_new_method_return(msg);
	}

	alert = g_new0(struct alert_data, 1);
	alert->srv = g_strdup(sender);
	alert->path = g_strdup(path);
	alert->category = category;
	alert->watcher = g_dbus_add_disconnect_watch(conn, alert->srv,
					watcher_disconnect, alert, NULL);

	if (alert->watcher == 0) {
		alert_data_destroy(alert);
		DBG("Could not register disconnect watcher");
		return btd_error_failed(msg,
				"Could not register disconnect watcher");
	}

	registered_alerts = g_slist_append(registered_alerts, alert);

	g_slist_foreach(alert_adapters, update_supported_categories, NULL);

	DBG("RegisterAlert(\"%s\", \"%s\")", alert->category, alert->path);

	return dbus_message_new_method_return(msg);
}

static void update_new_alert(gpointer data, gpointer user_data)
{
	struct alert_adapter *al_adapter = data;
	struct btd_adapter *adapter = al_adapter->adapter;
	uint8_t *value = user_data;

	attrib_db_update(adapter, al_adapter->hnd_value[NOTIFY_NEW_ALERT], NULL,
						&value[1], value[0], NULL);

	notify_devices(al_adapter, NOTIFY_NEW_ALERT, &value[1], value[0]);
}

static void update_phone_alerts(const char *category, const char *description)
{
	unsigned int i;

	if (g_str_equal(category, "ringer")) {
		if (g_str_equal(description, "enabled")) {
			ringer_setting = RINGER_NORMAL;
			pasp_notification(NOTIFY_RINGER_SETTING);
			return;
		} else if (g_str_equal(description, "disabled")) {
			ringer_setting = RINGER_SILENT;
			pasp_notification(NOTIFY_RINGER_SETTING);
			return;
		}
	}

	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
		if (g_str_equal(pasp_categories[i], category)) {
			if (g_str_equal(description, "active")) {
				alert_status |= (1 << i);
				pasp_notification(NOTIFY_ALERT_STATUS);
			} else if (g_str_equal(description, "not active")) {
				alert_status &= ~(1 << i);
				pasp_notification(NOTIFY_ALERT_STATUS);
			}
			break;
		}
	}
}

static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	const char *sender = dbus_message_get_sender(msg);
	const char *category, *description;
	struct alert_data *alert;
	uint16_t count;
	unsigned int i;
	size_t dlen;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
			DBUS_TYPE_UINT16, &count, DBUS_TYPE_STRING,
			&description, DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	alert = get_alert_data_by_category(category);
	if (!alert) {
		DBG("Category %s not registered", category);
		return btd_error_invalid_args(msg);
	}

	if (!g_str_equal(alert->srv, sender)) {
		DBG("Sender %s is not registered in category %s", sender,
								category);
		return btd_error_invalid_args(msg);
	}

	if (!valid_description(category, description)) {
		DBG("Description %s is invalid for %s category",
							description, category);
		return btd_error_invalid_args(msg);
	}

	if (!valid_count(category, count)) {
		DBG("Count %d is invalid for %s category", count, category);
		return btd_error_invalid_args(msg);
	}

	dlen = strlen(description);

	for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
		uint8_t value[NEW_ALERT_CHR_MAX_VALUE_SIZE + 1];
		uint8_t *ptr = value;

		if (!g_str_equal(anp_categories[i], category))
			continue;

		memset(value, 0, sizeof(value));

		*ptr++ = 2; /* Attribute value size */
		*ptr++ = i; /* Category ID (mandatory) */
		*ptr++ = count; /* Number of New Alert (mandatory) */
		/* Text String Information (optional) */
		strncpy((char *) ptr, description,
						NEW_ALERT_MAX_INFO_SIZE - 1);

		if (dlen > 0)
			*value += dlen + 1;

		g_slist_foreach(alert_adapters, update_new_alert, value);
	}

	if (pasp_category(category))
		update_phone_alerts(category, description);

	DBG("NewAlert(\"%s\", %d, \"%s\")", category, count, description);

	return dbus_message_new_method_return(msg);
}

static int agent_ringer_mute_once(void)
{
	struct alert_data *alert;
	DBusMessage *msg;

	alert = get_alert_data_by_category("ringer");
	if (!alert) {
		DBG("Category ringer is not registered");
		return -EINVAL;
	}

	msg = dbus_message_new_method_call(alert->srv, alert->path,
					ALERT_AGENT_INTERFACE, "MuteOnce");
	if (!msg)
		return -ENOMEM;

	dbus_message_set_no_reply(msg, TRUE);
	g_dbus_send_message(btd_get_dbus_connection(), msg);

	return 0;
}

static int agent_ringer_set_ringer(const char *mode)
{
	struct alert_data *alert;
	DBusMessage *msg;

	alert = get_alert_data_by_category("ringer");
	if (!alert) {
		DBG("Category ringer is not registered");
		return -EINVAL;
	}

	msg = dbus_message_new_method_call(alert->srv, alert->path,
					ALERT_AGENT_INTERFACE, "SetRinger");
	if (!msg)
		return -ENOMEM;

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &mode,
							DBUS_TYPE_INVALID);

	dbus_message_set_no_reply(msg, TRUE);
	g_dbus_send_message(btd_get_dbus_connection(), msg);

	return 0;
}

static void update_unread_alert(gpointer data, gpointer user_data)
{
	struct alert_adapter *al_adapter = data;
	struct btd_adapter *adapter = al_adapter->adapter;
	uint8_t *value = user_data;

	attrib_db_update(adapter,
			al_adapter->hnd_value[NOTIFY_UNREAD_ALERT], NULL, value,
			2, NULL);

	notify_devices(al_adapter, NOTIFY_UNREAD_ALERT, value, 2);
}

static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	const char *sender = dbus_message_get_sender(msg);
	struct alert_data *alert;
	const char *category;
	unsigned int i;
	uint16_t count;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
						DBUS_TYPE_UINT16, &count,
						DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	alert = get_alert_data_by_category(category);
	if (!alert) {
		DBG("Category %s not registered", category);
		return btd_error_invalid_args(msg);
	}

	if (!valid_count(category, count)) {
		DBG("Count %d is invalid for %s category", count, category);
		return btd_error_invalid_args(msg);
	}

	if (!g_str_equal(alert->srv, sender)) {
		DBG("Sender %s is not registered in category %s", sender,
								category);
		return btd_error_invalid_args(msg);
	}

	for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
		if (g_str_equal(anp_categories[i], category)) {
			uint8_t value[2];

			value[0] = i; /* Category ID */
			value[1] = count; /* Unread count */

			g_slist_foreach(alert_adapters, update_unread_alert,
									value);
		}
	}

	DBG("category %s, count %d", category, count);

	return dbus_message_new_method_return(msg);
}

static uint8_t ringer_cp_write(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	DBG("a = %p", a);

	if (a->len > 1) {
		DBG("Invalid command size (%zu)", a->len);
		return 0;
	}

	switch (a->data[0]) {
	case RINGER_SILENT_MODE:
		DBG("Silent Mode");
		agent_ringer_set_ringer("disabled");
		break;
	case RINGER_MUTE_ONCE:
		DBG("Mute Once");
		agent_ringer_mute_once();
		break;
	case RINGER_CANCEL_SILENT_MODE:
		DBG("Cancel Silent Mode");
		agent_ringer_set_ringer("enabled");
		break;
	default:
		DBG("Invalid command (0x%02x)", a->data[0]);
	}

	return 0;
}

static uint8_t alert_status_read(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	struct btd_adapter *adapter = user_data;

	DBG("a = %p", a);

	if (a->data == NULL || a->data[0] != alert_status)
		attrib_db_update(adapter, a->handle, NULL, &alert_status,
						sizeof(alert_status), NULL);

	return 0;
}

static uint8_t ringer_setting_read(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	struct btd_adapter *adapter = user_data;

	DBG("a = %p", a);

	if (a->data == NULL || a->data[0] != ringer_setting)
		attrib_db_update(adapter, a->handle, NULL, &ringer_setting,
						sizeof(ringer_setting), NULL);

	return 0;
}

static void register_phone_alert_service(struct alert_adapter *al_adapter)
{
	bt_uuid_t uuid;

	bt_uuid16_create(&uuid, PHONE_ALERT_STATUS_SVC_UUID);

	/* Phone Alert Status Service */
	gatt_service_add(al_adapter->adapter, GATT_PRIM_SVC_UUID, &uuid,
			/* Alert Status characteristic */
			GATT_OPT_CHR_UUID16, ALERT_STATUS_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ |
							GATT_CHR_PROP_NOTIFY,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
			alert_status_read, al_adapter->adapter,
			GATT_OPT_CCC_GET_HANDLE,
			&al_adapter->hnd_ccc[NOTIFY_ALERT_STATUS],
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->hnd_value[NOTIFY_ALERT_STATUS],
			/* Ringer Control Point characteristic */
			GATT_OPT_CHR_UUID16, RINGER_CP_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_WRITE_WITHOUT_RESP,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
			ringer_cp_write, NULL,
			/* Ringer Setting characteristic */
			GATT_OPT_CHR_UUID16, RINGER_SETTING_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ |
							GATT_CHR_PROP_NOTIFY,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
			ringer_setting_read, al_adapter->adapter,
			GATT_OPT_CCC_GET_HANDLE,
			&al_adapter->hnd_ccc[NOTIFY_RINGER_SETTING],
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->hnd_value[NOTIFY_RINGER_SETTING],
			GATT_OPT_INVALID);
}

static uint8_t supp_new_alert_cat_read(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	struct btd_adapter *adapter = user_data;
	uint8_t value[] = { 0x00, 0x00 };

	DBG("a = %p", a);

	if (a->data == NULL)
		attrib_db_update(adapter, a->handle, NULL, value, sizeof(value),
									NULL);

	return 0;
}

static uint8_t supp_unread_alert_cat_read(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	struct btd_adapter *adapter = user_data;
	uint8_t value[] = { 0x00, 0x00 };

	DBG("a = %p", a);

	if (a->data == NULL)
		attrib_db_update(adapter, a->handle, NULL, value, sizeof(value),
									NULL);

	return 0;
}

static uint8_t alert_notif_cp_write(struct attribute *a,
						struct btd_device *device,
						gpointer user_data)
{
	DBG("a = %p", a);

	if (a->len < 2)
		return 0;

	switch (a->data[0]) {
	case ENABLE_NEW_INCOMING:
		DBG("ENABLE_NEW_INCOMING: 0x%02x", a->data[1]);
		break;
	case ENABLE_UNREAD_CAT:
		DBG("ENABLE_UNREAD_CAT: 0x%02x", a->data[1]);
		break;
	case DISABLE_NEW_INCOMING:
		DBG("DISABLE_NEW_INCOMING: 0x%02x", a->data[1]);
		break;
	case DISABLE_UNREAD_CAT:
		DBG("DISABLE_UNREAD_CAT: 0x%02x", a->data[1]);
		break;
	case NOTIFY_NEW_INCOMING:
		DBG("NOTIFY_NEW_INCOMING: 0x%02x", a->data[1]);
		break;
	case NOTIFY_UNREAD_CAT:
		DBG("NOTIFY_UNREAD_CAT: 0x%02x", a->data[1]);
		break;
	default:
		DBG("0x%02x 0x%02x", a->data[0], a->data[1]);
	}

	return 0;
}

static void register_alert_notif_service(struct alert_adapter *al_adapter)
{
	bt_uuid_t uuid;

	bt_uuid16_create(&uuid, ALERT_NOTIF_SVC_UUID);

	/* Alert Notification Service */
	gatt_service_add(al_adapter->adapter, GATT_PRIM_SVC_UUID, &uuid,
			/* Supported New Alert Category */
			GATT_OPT_CHR_UUID16, SUPP_NEW_ALERT_CAT_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
			supp_new_alert_cat_read, al_adapter->adapter,
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->supp_new_alert_cat_handle,
			/* New Alert */
			GATT_OPT_CHR_UUID16, NEW_ALERT_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_NOTIFY,
			GATT_OPT_CCC_GET_HANDLE,
			&al_adapter->hnd_ccc[NOTIFY_NEW_ALERT],
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->hnd_value[NOTIFY_NEW_ALERT],
			/* Supported Unread Alert Category */
			GATT_OPT_CHR_UUID16, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
			supp_unread_alert_cat_read, al_adapter->adapter,
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->supp_unread_alert_cat_handle,
			/* Unread Alert Status */
			GATT_OPT_CHR_UUID16, UNREAD_ALERT_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_NOTIFY,
			GATT_OPT_CCC_GET_HANDLE,
			&al_adapter->hnd_ccc[NOTIFY_UNREAD_ALERT],
			GATT_OPT_CHR_VALUE_GET_HANDLE,
			&al_adapter->hnd_value[NOTIFY_UNREAD_ALERT],
			/* Alert Notification Control Point */
			GATT_OPT_CHR_UUID16, ALERT_NOTIF_CP_CHR_UUID,
			GATT_OPT_CHR_PROPS, GATT_CHR_PROP_WRITE,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
			alert_notif_cp_write, NULL,
			GATT_OPT_INVALID);
}

static int alert_server_probe(struct btd_profile *p,
						struct btd_adapter *adapter)
{
	struct alert_adapter *al_adapter;

	al_adapter = g_new0(struct alert_adapter, 1);
	al_adapter->adapter = btd_adapter_ref(adapter);

	alert_adapters = g_slist_append(alert_adapters, al_adapter);

	register_phone_alert_service(al_adapter);
	register_alert_notif_service(al_adapter);

	return 0;
}

static void alert_server_remove(struct btd_profile *p,
						struct btd_adapter *adapter)
{
	struct alert_adapter *al_adapter;

	al_adapter = find_alert_adapter(adapter);
	if (!al_adapter)
		return;

	alert_adapters = g_slist_remove(alert_adapters, al_adapter);
	btd_adapter_unref(al_adapter->adapter);

	g_free(al_adapter);
}

static struct btd_profile alert_profile = {
	.name = "gatt-alert-server",
	.adapter_probe = alert_server_probe,
	.adapter_remove = alert_server_remove,
};

static const GDBusMethodTable alert_methods[] = {
	{ GDBUS_METHOD("RegisterAlert",
			GDBUS_ARGS({ "category", "s" },
				   { "agent", "o" }), NULL,
			register_alert) },
	{ GDBUS_METHOD("NewAlert",
			GDBUS_ARGS({ "category", "s" },
				   { "count", "q" },
				   { "description", "s" }), NULL,
			new_alert) },
	{ GDBUS_METHOD("UnreadAlert",
			GDBUS_ARGS({ "category", "s" }, { "count", "q" }), NULL,
			unread_alert) },
	{ }
};

static int alert_server_init(void)
{
	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					ALERT_OBJECT_PATH, ALERT_INTERFACE,
					alert_methods, NULL, NULL, NULL,
					alert_destroy)) {
		error("D-Bus failed to register %s interface",
							ALERT_INTERFACE);
		return -EIO;
	}

	return btd_profile_register(&alert_profile);
}

static void alert_server_exit(void)
{
	btd_profile_unregister(&alert_profile);

	g_dbus_unregister_interface(btd_get_dbus_connection(),
					ALERT_OBJECT_PATH, ALERT_INTERFACE);
}

static int alert_init(void)
{
	return alert_server_init();
}

static void alert_exit(void)
{
	alert_server_exit();
}

BLUETOOTH_PLUGIN_DEFINE(alert, VERSION,
			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
			alert_init, alert_exit)
