/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Tieto Poland
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <stdbool.h>
#include <glib.h>
#include <gdbus/gdbus.h>

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

/* min length for ATT indication or notification: opcode (1b) + handle (2b) */
#define ATT_HDR_LEN 3

#define ATT_TIMEOUT 30

#define CYCLINGSPEED_INTERFACE		"org.bluez.CyclingSpeed1"
#define CYCLINGSPEED_MANAGER_INTERFACE	"org.bluez.CyclingSpeedManager1"
#define CYCLINGSPEED_WATCHER_INTERFACE	"org.bluez.CyclingSpeedWatcher1"

#define WHEEL_REV_SUPPORT		0x01
#define CRANK_REV_SUPPORT		0x02
#define MULTI_SENSOR_LOC_SUPPORT	0x04

#define WHEEL_REV_PRESENT	0x01
#define CRANK_REV_PRESENT	0x02

#define SET_CUMULATIVE_VALUE		0x01
#define START_SENSOR_CALIBRATION	0x02
#define UPDATE_SENSOR_LOC		0x03
#define REQUEST_SUPPORTED_SENSOR_LOC	0x04
#define RESPONSE_CODE			0x10

#define RSP_SUCCESS		0x01
#define RSP_NOT_SUPPORTED	0x02
#define RSP_INVALID_PARAM	0x03
#define RSP_FAILED		0x04

struct csc;

struct controlpoint_req {
	struct csc		*csc;
	uint8_t			opcode;
	guint			timeout;
	GDBusPendingReply	reply_id;
	DBusMessage		*msg;

	uint8_t			pending_location;
};

struct csc_adapter {
	struct btd_adapter	*adapter;
	GSList			*devices;	/* list of registered devices */
	GSList			*watchers;
};

struct csc {
	struct btd_device	*dev;
	struct csc_adapter	*cadapter;

	GAttrib			*attrib;
	guint			attioid;
	/* attio id for measurement characteristics value notifications */
	guint			attio_measurement_id;
	/* attio id for SC Control Point characteristics value indications */
	guint			attio_controlpoint_id;

	struct att_range	*svc_range;

	uint16_t		measurement_ccc_handle;
	uint16_t		controlpoint_val_handle;

	uint16_t		feature;
	gboolean		has_location;
	uint8_t			location;
	uint8_t			num_locations;
	uint8_t			*locations;

	struct controlpoint_req	*pending_req;
};

struct watcher {
	struct csc_adapter	*cadapter;
	guint			id;
	char			*srv;
	char			*path;
};

struct measurement {
	struct csc	*csc;

	bool		has_wheel_rev;
	uint32_t	wheel_rev;
	uint16_t	last_wheel_time;

	bool		has_crank_rev;
	uint16_t	crank_rev;
	uint16_t	last_crank_time;
};

struct characteristic {
	struct csc	*csc;
	char		uuid[MAX_LEN_UUID_STR + 1];
};

static GSList *csc_adapters = NULL;

static const char * const location_enum[] = {
	"other", "top-of-shoe", "in-shoe", "hip", "front-wheel", "left-crank",
	"right-crank", "left-pedal", "right-pedal", "front-hub",
	"rear-dropout", "chainstay", "rear-wheel", "rear-hub"
};

static const char *location2str(uint8_t value)
{
	if (value < G_N_ELEMENTS(location_enum))
		return location_enum[value];

	info("Body Sensor Location [%d] is RFU", value);

	return location_enum[0];
}

static int str2location(const char *location)
{
	size_t i;

	for (i = 0; i < G_N_ELEMENTS(location_enum); i++)
		if (!strcmp(location_enum[i], location))
			return i;

	return -1;
}

static int cmp_adapter(gconstpointer a, gconstpointer b)
{
	const struct csc_adapter *cadapter = a;
	const struct btd_adapter *adapter = b;

	if (adapter == cadapter->adapter)
		return 0;

	return -1;
}

static int cmp_device(gconstpointer a, gconstpointer b)
{
	const struct csc *csc = a;
	const struct btd_device *dev = b;

	if (dev == csc->dev)
		return 0;

	return -1;
}

static int cmp_watcher(gconstpointer a, gconstpointer b)
{
	const struct watcher *watcher = a;
	const struct watcher *match = b;
	int ret;

	ret = g_strcmp0(watcher->srv, match->srv);
	if (ret != 0)
		return ret;

	return g_strcmp0(watcher->path, match->path);
}

static struct csc_adapter *find_csc_adapter(struct btd_adapter *adapter)
{
	GSList *l = g_slist_find_custom(csc_adapters, adapter, cmp_adapter);

	if (!l)
		return NULL;

	return l->data;
}

static void destroy_watcher(gpointer user_data)
{
	struct watcher *watcher = user_data;

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

static struct watcher *find_watcher(GSList *list, const char *sender,
							const char *path)
{
	struct watcher *match;
	GSList *l;

	match = g_new0(struct watcher, 1);
	match->srv = g_strdup(sender);
	match->path = g_strdup(path);

	l = g_slist_find_custom(list, match, cmp_watcher);
	destroy_watcher(match);

	if (l != NULL)
		return l->data;

	return NULL;
}

static void remove_watcher(gpointer user_data)
{
	struct watcher *watcher = user_data;

	g_dbus_remove_watch(btd_get_dbus_connection(), watcher->id);
}

static void destroy_csc_adapter(gpointer user_data)
{
	struct csc_adapter *cadapter = user_data;

	g_slist_free_full(cadapter->watchers, remove_watcher);

	g_free(cadapter);
}

static void destroy_csc(gpointer user_data)
{
	struct csc *csc = user_data;

	if (csc->attioid > 0)
		btd_device_remove_attio_callback(csc->dev, csc->attioid);

	if (csc->attrib != NULL) {
		g_attrib_unregister(csc->attrib, csc->attio_measurement_id);
		g_attrib_unregister(csc->attrib, csc->attio_controlpoint_id);
		g_attrib_unref(csc->attrib);
	}

	btd_device_unref(csc->dev);
	g_free(csc->svc_range);
	g_free(csc->locations);
	g_free(csc);
}

static void char_write_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	char *msg = user_data;

	if (status != 0)
		error("%s failed", msg);

	g_free(msg);
}

static gboolean controlpoint_timeout(gpointer user_data)
{
	struct controlpoint_req *req = user_data;

	if (req->opcode == UPDATE_SENSOR_LOC) {
		g_dbus_pending_property_error(req->reply_id,
						ERROR_INTERFACE ".Failed",
						"Operation failed (timeout)");
	} else if (req->opcode == SET_CUMULATIVE_VALUE) {
		DBusMessage *reply;

		reply = btd_error_failed(req->msg,
						"Operation failed (timeout)");

		g_dbus_send_message(btd_get_dbus_connection(), reply);

		dbus_message_unref(req->msg);
	}

	req->csc->pending_req = NULL;
	g_free(req);

	return FALSE;
}

static void controlpoint_write_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct controlpoint_req *req = user_data;

	if (status == 0) {
		req->timeout = g_timeout_add_seconds(ATT_TIMEOUT,
							controlpoint_timeout,
							req);
		return;
	}

	error("SC Control Point write failed (opcode=%d)", req->opcode);

	if (req->opcode == UPDATE_SENSOR_LOC) {
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".Failed",
					"Operation failed (%d)", status);
	} else if  (req->opcode == SET_CUMULATIVE_VALUE) {
		DBusMessage *reply;

		reply = btd_error_failed(req->msg, "Operation failed");

		g_dbus_send_message(btd_get_dbus_connection(), reply);

		dbus_message_unref(req->msg);
	}

	req->csc->pending_req = NULL;
	g_free(req);
}

static void read_supported_locations(struct csc *csc)
{
	struct controlpoint_req *req;

	req = g_new0(struct controlpoint_req, 1);
	req->csc = csc;
	req->opcode = REQUEST_SUPPORTED_SENSOR_LOC;

	csc->pending_req = req;

	gatt_write_char(csc->attrib, csc->controlpoint_val_handle,
					&req->opcode, sizeof(req->opcode),
					controlpoint_write_cb, req);
}

static void read_feature_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct csc *csc = user_data;
	uint8_t value[2];
	ssize_t vlen;

	if (status) {
		error("CSC Feature read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error");
		return;
	}

	if (vlen != sizeof(value)) {
		error("Invalid value length for CSC Feature");
		return;
	}

	csc->feature = att_get_u16(value);

	if ((csc->feature & MULTI_SENSOR_LOC_SUPPORT)
						&& (csc->locations == NULL))
		read_supported_locations(csc);
}

static void read_location_cb(guint8 status, const guint8 *pdu,
						guint16 len, gpointer user_data)
{
	struct csc *csc = user_data;
	uint8_t value;
	ssize_t vlen;

	if (status) {
		error("Sensor Location read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, &value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error");
		return;
	}

	if (vlen != sizeof(value)) {
		error("Invalid value length for Sensor Location");
		return;
	}

	csc->has_location = TRUE;
	csc->location = value;

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
					device_get_path(csc->dev),
					CYCLINGSPEED_INTERFACE, "Location");
}

static void discover_desc_cb(guint8 status, const guint8 *pdu,
					guint16 len, gpointer user_data)
{
	struct characteristic *ch = user_data;
	struct att_data_list *list = NULL;
	uint8_t format;
	int i;

	if (status != 0) {
		error("Discover %s descriptors failed: %s", ch->uuid,
							att_ecode2str(status));
		goto done;
	}

	list = dec_find_info_resp(pdu, len, &format);
	if (list == NULL)
		goto done;

	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
		goto done;

	for (i = 0; i < list->num; i++) {
		uint8_t *value;
		uint16_t handle, uuid;
		uint8_t attr_val[2];
		char *msg;

		value = list->data[i];
		handle = att_get_u16(value);
		uuid = att_get_u16(value + 2);

		if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
			continue;

		if (g_strcmp0(ch->uuid, CSC_MEASUREMENT_UUID) == 0) {
			ch->csc->measurement_ccc_handle = handle;

			if (g_slist_length(ch->csc->cadapter->watchers) == 0) {
				att_put_u16(0x0000, attr_val);
				msg = g_strdup("Disable measurement");
			} else {
				att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT,
								attr_val);
				msg = g_strdup("Enable measurement");
			}

		} else if (g_strcmp0(ch->uuid, SC_CONTROL_POINT_UUID) == 0) {
			att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, attr_val);
			msg = g_strdup("Enable SC Control Point indications");
		} else {
			break;
		}

		gatt_write_char(ch->csc->attrib, handle, attr_val,
					sizeof(attr_val), char_write_cb, msg);

		/* We only want CCC, can break here */
		break;
	}

done:
	if (list)
		att_data_list_free(list);
	g_free(ch);
}

static void discover_desc(struct csc *csc, struct gatt_char *c,
						struct gatt_char *c_next)
{
	struct characteristic *ch;
	uint16_t start, end;

	start = c->value_handle + 1;

	if (c_next != NULL) {
		if (start == c_next->handle)
			return;
		end = c_next->handle - 1;
	} else if (c->value_handle != csc->svc_range->end) {
		end = csc->svc_range->end;
	} else {
		return;
	}

	ch = g_new0(struct characteristic, 1);
	ch->csc = csc;
	memcpy(ch->uuid, c->uuid, sizeof(c->uuid));

	gatt_discover_char_desc(csc->attrib, start, end, discover_desc_cb, ch);
}

static void update_watcher(gpointer data, gpointer user_data)
{
	struct watcher *w = data;
	struct measurement *m = user_data;
	struct csc *csc = m->csc;
	const char *path = device_get_path(csc->dev);
	DBusMessageIter iter;
	DBusMessageIter dict;
	DBusMessage *msg;

	msg = dbus_message_new_method_call(w->srv, w->path,
			CYCLINGSPEED_WATCHER_INTERFACE, "MeasurementReceived");
	if (msg == NULL)
		return;

	dbus_message_iter_init_append(msg, &iter);

	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH , &path);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	if (m->has_wheel_rev) {
		dict_append_entry(&dict, "WheelRevolutions",
					DBUS_TYPE_UINT32, &m->wheel_rev);
		dict_append_entry(&dict, "LastWheelEventTime",
					DBUS_TYPE_UINT16, &m->last_wheel_time);
	}

	if (m->has_crank_rev) {
		dict_append_entry(&dict, "CrankRevolutions",
					DBUS_TYPE_UINT16, &m->crank_rev);
		dict_append_entry(&dict, "LastCrankEventTime",
					DBUS_TYPE_UINT16, &m->last_crank_time);
	}

	dbus_message_iter_close_container(&iter, &dict);

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

static void process_measurement(struct csc *csc, const uint8_t *pdu,
								uint16_t len)
{
	struct measurement m;
	uint8_t flags;

	flags = *pdu;

	pdu++;
	len--;

	memset(&m, 0, sizeof(m));

	if ((flags & WHEEL_REV_PRESENT) && (csc->feature & WHEEL_REV_SUPPORT)) {
		if (len < 6) {
			error("Wheel revolutions data fields missing");
			return;
		}

		m.has_wheel_rev = true;
		m.wheel_rev = att_get_u32(pdu);
		m.last_wheel_time = att_get_u16(pdu + 4);
		pdu += 6;
		len -= 6;
	}

	if ((flags & CRANK_REV_PRESENT) && (csc->feature & CRANK_REV_SUPPORT)) {
		if (len < 4) {
			error("Crank revolutions data fields missing");
			return;
		}

		m.has_crank_rev = true;
		m.crank_rev = att_get_u16(pdu);
		m.last_crank_time = att_get_u16(pdu + 2);
		pdu += 4;
		len -= 4;
	}

	/* Notify all registered watchers */
	m.csc = csc;
	g_slist_foreach(csc->cadapter->watchers, update_watcher, &m);
}

static void measurement_notify_handler(const uint8_t *pdu, uint16_t len,
							gpointer user_data)
{
	struct csc *csc = user_data;

	/* should be at least opcode (1b) + handle (2b) */
	if (len < 3) {
		error("Invalid PDU received");
		return;
	}

	process_measurement(csc, pdu + 3, len - 3);
}

static void controlpoint_property_reply(struct controlpoint_req *req,
								uint8_t code)
{
	switch (code) {
	case RSP_SUCCESS:
		g_dbus_pending_property_success(req->reply_id);
		break;

	case RSP_NOT_SUPPORTED:
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".NotSupported",
					"Feature is not supported");
		break;

	case RSP_INVALID_PARAM:
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		break;

	case RSP_FAILED:
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".Failed",
					"Operation failed");
		break;

	default:
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".Failed",
					"Operation failed (%d)", code);
		break;
	}
}

static void controlpoint_method_reply(struct controlpoint_req *req,
								uint8_t code)
{
	DBusMessage *reply;

	switch (code) {
	case RSP_SUCCESS:
		reply = dbus_message_new_method_return(req->msg);
		break;
	case RSP_NOT_SUPPORTED:
		reply = btd_error_not_supported(req->msg);
		break;
	case RSP_INVALID_PARAM:
		reply = btd_error_invalid_args(req->msg);
		break;
	case RSP_FAILED:
		reply = btd_error_failed(req->msg, "Failed");
		break;
	default:
		reply = btd_error_failed(req->msg, "Unknown error");
		break;
	}

	g_dbus_send_message(btd_get_dbus_connection(), reply);

	dbus_message_unref(req->msg);
}

static void controlpoint_ind_handler(const uint8_t *pdu, uint16_t len,
							gpointer user_data)
{
	struct csc *csc = user_data;
	struct controlpoint_req *req = csc->pending_req;
	uint8_t opcode;
	uint8_t req_opcode;
	uint8_t rsp_code;
	uint8_t *opdu;
	uint16_t olen;
	size_t plen;

	if (len < ATT_HDR_LEN) {
		error("Invalid PDU received");
		return;
	}

	/* skip ATT header */
	pdu += ATT_HDR_LEN;
	len -= ATT_HDR_LEN;

	if (len < 1) {
		error("Op Code missing");
		goto done;
	}

	opcode = *pdu;
	pdu++;
	len--;

	if (opcode != RESPONSE_CODE) {
		DBG("Unsupported Op Code received (%d)", opcode);
		goto done;
	}

	if (len < 2) {
		error("Invalid Response Code PDU received");
		goto done;
	}

	req_opcode = *pdu;
	rsp_code = *(pdu + 1);
	pdu += 2;
	len -= 2;

	if (req == NULL || req->opcode != req_opcode) {
		DBG("Indication received without pending request");
		goto done;
	}

	switch (req->opcode) {
	case SET_CUMULATIVE_VALUE:
		controlpoint_method_reply(req, rsp_code);
		break;

	case REQUEST_SUPPORTED_SENSOR_LOC:
		if (rsp_code == RSP_SUCCESS) {
			csc->num_locations = len;
			csc->locations = g_memdup(pdu, len);
		} else {
			error("Failed to read Supported Sendor Locations");
		}
		break;

	case UPDATE_SENSOR_LOC:
		csc->location = req->pending_location;

		controlpoint_property_reply(req, rsp_code);

		g_dbus_emit_property_changed(btd_get_dbus_connection(),
					device_get_path(csc->dev),
					CYCLINGSPEED_INTERFACE, "Location");
		break;
	}

	csc->pending_req = NULL;
	g_source_remove(req->timeout);
	g_free(req);

done:
	opdu = g_attrib_get_buffer(csc->attrib, &plen);
	olen = enc_confirmation(opdu, plen);
	if (olen > 0)
		g_attrib_send(csc->attrib, 0, opdu, olen, NULL, NULL, NULL);
}

static void discover_char_cb(GSList *chars, guint8 status, gpointer user_data)
{
	struct csc *csc = user_data;
	uint16_t feature_val_handle = 0;

	if (status) {
		error("Discover CSCS characteristics: %s",
							att_ecode2str(status));
		return;
	}

	for (; chars; chars = chars->next) {
		struct gatt_char *c = chars->data;
		struct gatt_char *c_next =
				(chars->next ? chars->next->data : NULL);

		if (g_strcmp0(c->uuid, CSC_MEASUREMENT_UUID) == 0) {
			csc->attio_measurement_id =
				g_attrib_register(csc->attrib,
					ATT_OP_HANDLE_NOTIFY, c->value_handle,
					measurement_notify_handler, csc, NULL);

			discover_desc(csc, c, c_next);
		} else if (g_strcmp0(c->uuid, CSC_FEATURE_UUID) == 0) {
			feature_val_handle = c->value_handle;
		} else if (g_strcmp0(c->uuid, SENSOR_LOCATION_UUID) == 0) {
			DBG("Sensor Location supported");
			gatt_read_char(csc->attrib, c->value_handle,
							read_location_cb, csc);
		} else if (g_strcmp0(c->uuid, SC_CONTROL_POINT_UUID) == 0) {
			DBG("SC Control Point supported");
			csc->controlpoint_val_handle = c->value_handle;

			csc->attio_controlpoint_id = g_attrib_register(
					csc->attrib, ATT_OP_HANDLE_IND,
					c->value_handle,
					controlpoint_ind_handler, csc, NULL);

			discover_desc(csc, c, c_next);
		}
	}

	if (feature_val_handle > 0)
		gatt_read_char(csc->attrib, feature_val_handle,
							read_feature_cb, csc);
}

static void enable_measurement(gpointer data, gpointer user_data)
{
	struct csc *csc = data;
	uint16_t handle = csc->measurement_ccc_handle;
	uint8_t value[2];
	char *msg;

	if (csc->attrib == NULL || !handle)
		return;

	att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
	msg = g_strdup("Enable measurement");

	gatt_write_char(csc->attrib, handle, value, sizeof(value),
							char_write_cb, msg);
}

static void disable_measurement(gpointer data, gpointer user_data)
{
	struct csc *csc = data;
	uint16_t handle = csc->measurement_ccc_handle;
	uint8_t value[2];
	char *msg;

	if (csc->attrib == NULL || !handle)
		return;

	att_put_u16(0x0000, value);
	msg = g_strdup("Disable measurement");

	gatt_write_char(csc->attrib, handle, value, sizeof(value),
							char_write_cb, msg);
}

static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
	struct csc *csc = user_data;

	DBG("");

	csc->attrib = g_attrib_ref(attrib);

	gatt_discover_char(csc->attrib, csc->svc_range->start,
						csc->svc_range->end, NULL,
						discover_char_cb, csc);
}

static void attio_disconnected_cb(gpointer user_data)
{
	struct csc *csc = user_data;

	DBG("");

	if (csc->attio_measurement_id > 0) {
		g_attrib_unregister(csc->attrib, csc->attio_measurement_id);
		csc->attio_measurement_id = 0;
	}

	if (csc->attio_controlpoint_id > 0) {
		g_attrib_unregister(csc->attrib, csc->attio_controlpoint_id);
		csc->attio_controlpoint_id = 0;
	}

	g_attrib_unref(csc->attrib);
	csc->attrib = NULL;
}

static void watcher_exit_cb(DBusConnection *conn, void *user_data)
{
	struct watcher *watcher = user_data;
	struct csc_adapter *cadapter = watcher->cadapter;

	DBG("cycling watcher [%s] disconnected", watcher->path);

	cadapter->watchers = g_slist_remove(cadapter->watchers, watcher);
	g_dbus_remove_watch(conn, watcher->id);

	if (g_slist_length(cadapter->watchers) == 0)
		g_slist_foreach(cadapter->devices, disable_measurement, 0);
}

static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct csc_adapter *cadapter = data;
	struct watcher *watcher;
	const char *sender = dbus_message_get_sender(msg);
	char *path;

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

	watcher = find_watcher(cadapter->watchers, sender, path);
	if (watcher != NULL)
		return btd_error_already_exists(msg);

	watcher = g_new0(struct watcher, 1);
	watcher->cadapter = cadapter;
	watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit_cb,
						watcher, destroy_watcher);
	watcher->srv = g_strdup(sender);
	watcher->path = g_strdup(path);

	if (g_slist_length(cadapter->watchers) == 0)
		g_slist_foreach(cadapter->devices, enable_measurement, 0);

	cadapter->watchers = g_slist_prepend(cadapter->watchers, watcher);

	DBG("cycling watcher [%s] registered", path);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct csc_adapter *cadapter = data;
	struct watcher *watcher;
	const char *sender = dbus_message_get_sender(msg);
	char *path;

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

	watcher = find_watcher(cadapter->watchers, sender, path);
	if (watcher == NULL)
		return btd_error_does_not_exist(msg);

	cadapter->watchers = g_slist_remove(cadapter->watchers, watcher);
	g_dbus_remove_watch(conn, watcher->id);

	if (g_slist_length(cadapter->watchers) == 0)
		g_slist_foreach(cadapter->devices, disable_measurement, 0);

	DBG("cycling watcher [%s] unregistered", path);

	return dbus_message_new_method_return(msg);
}

static const GDBusMethodTable cyclingspeed_manager_methods[] = {
	{ GDBUS_METHOD("RegisterWatcher",
			GDBUS_ARGS({ "agent", "o" }), NULL,
			register_watcher) },
	{ GDBUS_METHOD("UnregisterWatcher",
			GDBUS_ARGS({ "agent", "o" }), NULL,
			unregister_watcher) },
	{ }
};

static int csc_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
	struct csc_adapter *cadapter;

	cadapter = g_new0(struct csc_adapter, 1);
	cadapter->adapter = adapter;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
						adapter_get_path(adapter),
						CYCLINGSPEED_MANAGER_INTERFACE,
						cyclingspeed_manager_methods,
						NULL, NULL, cadapter,
						destroy_csc_adapter)) {
		error("D-Bus failed to register %s interface",
						CYCLINGSPEED_MANAGER_INTERFACE);
		destroy_csc_adapter(cadapter);
		return -EIO;
	}

	csc_adapters = g_slist_prepend(csc_adapters, cadapter);

	return 0;
}

static void csc_adapter_remove(struct btd_profile *p,
						struct btd_adapter *adapter)
{
	struct csc_adapter *cadapter;

	cadapter = find_csc_adapter(adapter);
	if (cadapter == NULL)
		return;

	csc_adapters = g_slist_remove(csc_adapters, cadapter);

	g_dbus_unregister_interface(btd_get_dbus_connection(),
					adapter_get_path(cadapter->adapter),
					CYCLINGSPEED_MANAGER_INTERFACE);
}

static gboolean property_get_location(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct csc *csc = data;
	const char *loc;

	if (!csc->has_location)
		return FALSE;

	loc = location2str(csc->location);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &loc);

	return TRUE;
}

static void property_set_location(const GDBusPropertyTable *property,
					DBusMessageIter *iter,
					GDBusPendingPropertySet id, void *data)
{
	struct csc *csc = data;
	char *loc;
	int loc_val;
	uint8_t att_val[2];
	struct controlpoint_req *req;

	if (csc->pending_req != NULL) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InProgress",
					"Operation already in progress");
		return;
	}

	if (!(csc->feature & MULTI_SENSOR_LOC_SUPPORT)) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".NotSupported",
					"Feature is not supported");
		return;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	dbus_message_iter_get_basic(iter, &loc);

	loc_val = str2location(loc);

	if (loc_val < 0) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	req = g_new(struct controlpoint_req, 1);
	req->csc = csc;
	req->reply_id = id;
	req->opcode = UPDATE_SENSOR_LOC;
	req->pending_location = loc_val;

	csc->pending_req = req;

	att_val[0] = UPDATE_SENSOR_LOC;
	att_val[1] = loc_val;

	gatt_write_char(csc->attrib, csc->controlpoint_val_handle, att_val,
				sizeof(att_val), controlpoint_write_cb, req);
}

static gboolean property_exists_location(const GDBusPropertyTable *property,
								void *data)
{
	struct csc *csc = data;

	return csc->has_location;
}

static gboolean property_get_locations(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct csc *csc = data;
	DBusMessageIter entry;
	int i;

	if (!(csc->feature & MULTI_SENSOR_LOC_SUPPORT))
		return FALSE;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
					DBUS_TYPE_STRING_AS_STRING, &entry);
	for (i = 0; i < csc->num_locations; i++) {
		char *loc = g_strdup(location2str(csc->locations[i]));
		dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &loc);
		g_free(loc);
	}

	dbus_message_iter_close_container(iter, &entry);

	return TRUE;
}

static gboolean property_exists_locations(const GDBusPropertyTable *property,
								void *data)
{
	struct csc *csc = data;

	return !!(csc->feature & MULTI_SENSOR_LOC_SUPPORT);
}

static gboolean property_get_wheel_rev_sup(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct csc *csc = data;
	dbus_bool_t val;

	val = !!(csc->feature & WHEEL_REV_SUPPORT);
	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);

	return TRUE;
}

static gboolean property_get_multi_loc_sup(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct csc *csc = data;
	dbus_bool_t val;

	val = !!(csc->feature & MULTI_SENSOR_LOC_SUPPORT);
	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);

	return TRUE;
}

static const GDBusPropertyTable cyclingspeed_device_properties[] = {
	{ "Location", "s", property_get_location, property_set_location,
						property_exists_location },
	{ "SupportedLocations", "as", property_get_locations, NULL,
						property_exists_locations },
	{ "WheelRevolutionDataSupported", "b", property_get_wheel_rev_sup },
	{ "MultipleLocationsSupported", "b", property_get_multi_loc_sup },
	{ }
};

static DBusMessage *set_cumulative_wheel_rev(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct csc *csc = data;
	dbus_uint32_t value;
	struct controlpoint_req *req;
	uint8_t att_val[5]; /* uint8 opcode + uint32 value */

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &value,
							DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	if (csc->pending_req != NULL)
		return btd_error_in_progress(msg);

	req = g_new(struct controlpoint_req, 1);
	req->csc = csc;
	req->opcode = SET_CUMULATIVE_VALUE;
	req->msg = dbus_message_ref(msg);

	csc->pending_req = req;

	att_val[0] = SET_CUMULATIVE_VALUE;
	att_put_u32(value, att_val + 1);

	gatt_write_char(csc->attrib, csc->controlpoint_val_handle, att_val,
		sizeof(att_val), controlpoint_write_cb, req);

	return NULL;
}

static const GDBusMethodTable cyclingspeed_device_methods[] = {
	{ GDBUS_ASYNC_METHOD("SetCumulativeWheelRevolutions",
				GDBUS_ARGS({ "value", "u" }), NULL,
						set_cumulative_wheel_rev) },
	{ }
};

static int csc_device_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct btd_adapter *adapter;
	struct csc_adapter *cadapter;
	struct csc *csc;
	struct gatt_primary *prim;

	prim = btd_device_get_primary(device, CYCLING_SC_UUID);
	if (prim == NULL)
		return -EINVAL;

	adapter = device_get_adapter(device);

	cadapter = find_csc_adapter(adapter);
	if (cadapter == NULL)
		return -1;

	csc = g_new0(struct csc, 1);
	csc->dev = btd_device_ref(device);
	csc->cadapter = cadapter;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
						device_get_path(device),
						CYCLINGSPEED_INTERFACE,
						cyclingspeed_device_methods,
						NULL,
						cyclingspeed_device_properties,
						csc, destroy_csc)) {
		error("D-Bus failed to register %s interface",
						CYCLINGSPEED_INTERFACE);
		destroy_csc(csc);
		return -EIO;
	}

	csc->svc_range = g_new0(struct att_range, 1);
	csc->svc_range->start = prim->range.start;
	csc->svc_range->end = prim->range.end;

	cadapter->devices = g_slist_prepend(cadapter->devices, csc);

	csc->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
						attio_disconnected_cb, csc);

	return 0;
}

static void csc_device_remove(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct btd_adapter *adapter;
	struct csc_adapter *cadapter;
	struct csc *csc;
	GSList *l;

	adapter = device_get_adapter(device);

	cadapter = find_csc_adapter(adapter);
	if (cadapter == NULL)
		return;

	l = g_slist_find_custom(cadapter->devices, device, cmp_device);
	if (l == NULL)
		return;

	csc = l->data;

	cadapter->devices = g_slist_remove(cadapter->devices, csc);

	g_dbus_unregister_interface(btd_get_dbus_connection(),
						device_get_path(device),
						CYCLINGSPEED_INTERFACE);
}

static struct btd_profile cscp_profile = {
	.name		= "Cycling Speed and Cadence GATT Driver",
	.remote_uuid	= CYCLING_SC_UUID,

	.adapter_probe	= csc_adapter_probe,
	.adapter_remove	= csc_adapter_remove,

	.device_probe	= csc_device_probe,
	.device_remove	= csc_device_remove,
};

static int cyclingspeed_init(void)
{
	return btd_profile_register(&cscp_profile);
}

static void cyclingspeed_exit(void)
{
	btd_profile_unregister(&cscp_profile);
}

BLUETOOTH_PLUGIN_DEFINE(cyclingspeed, VERSION,
					BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
					cyclingspeed_init, cyclingspeed_exit)
