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

#include "plugin.h"
#include "hcid.h"
#include "log.h"
#include "gattrib.h"
#include "gatt-service.h"
#include "att.h"
#include "attrib-server.h"

/* FIXME: Not defined by SIG? UUID128? */
#define OPCODES_SUPPORTED_UUID          0xA001
#define BATTERY_STATE_SVC_UUID		0xA002
#define BATTERY_STATE_UUID		0xA003
#define THERM_HUMIDITY_SVC_UUID		0xA004
#define MANUFACTURER_SVC_UUID		0xA005
#define TEMPERATURE_UUID		0xA006
#define FMT_CELSIUS_UUID		0xA007
#define FMT_OUTSIDE_UUID		0xA008
#define RELATIVE_HUMIDITY_UUID		0xA009
#define FMT_PERCENT_UUID		0xA00A
#define BLUETOOTH_SIG_UUID		0xA00B
#define MANUFACTURER_NAME_UUID		0xA00C
#define MANUFACTURER_SERIAL_UUID	0xA00D
#define VENDOR_SPECIFIC_SVC_UUID	0xA00E
#define VENDOR_SPECIFIC_TYPE_UUID	0xA00F
#define FMT_KILOGRAM_UUID		0xA010
#define FMT_HANGING_UUID		0xA011

static GSList *sdp_handles = NULL;

static uint8_t battery_state_read(struct attribute *a, gpointer user_data)
{
	uint8_t value;

	value = 0x04;
	attrib_db_update(a->handle, NULL, &value, sizeof(value), NULL);

	return 0;
}

static gboolean register_battery_service(void)
{
	return gatt_service_add(GATT_PRIM_SVC_UUID, BATTERY_STATE_SVC_UUID,
			/* battery state characteristic */
			GATT_OPT_CHR_UUID, BATTERY_STATE_UUID,
			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
							ATT_CHAR_PROPER_NOTIFY,
			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, battery_state_read,

			GATT_OPT_INVALID);
}

static void register_termometer_service(const uint16_t manuf1[2],
						const uint16_t manuf2[2])
{
	const char *desc_out_temp = "Outside Temperature";
	const char *desc_out_hum = "Outside Relative Humidity";
	uint16_t start_handle, h;
	const int svc_size = 11;
	uint32_t sdp_handle;
	uint8_t atval[256];
	bt_uuid_t uuid;
	int len;

	start_handle = attrib_db_find_avail(svc_size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		return;
	}

	DBG("start_handle=0x%04x manuf1=0x%04x-0x%04x, manuf2=0x%04x-0x%04x",
		start_handle, manuf1[0], manuf1[1], manuf2[0], manuf2[1]);

	h = start_handle;

	/* Thermometer: primary service definition */
	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
	att_put_u16(THERM_HUMIDITY_SVC_UUID, &atval[0]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);

	/* Thermometer: Include */
	if (manuf1[0] && manuf1[1]) {
		att_put_u16(manuf1[0], &atval[0]);
		att_put_u16(manuf1[1], &atval[2]);
		att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]);
		attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval,
									6);
	}

	/* Thermometer: Include */
	if (manuf2[0] && manuf2[1]) {
		att_put_u16(manuf2[0], &atval[0]);
		att_put_u16(manuf2[1], &atval[2]);
		att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[4]);
		attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval,
									6);
	}

	/* Thermometer: temperature characteristic */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(TEMPERATURE_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Thermometer: temperature characteristic value */
	bt_uuid16_create(&uuid, TEMPERATURE_UUID);
	atval[0] = 0x8A;
	atval[1] = 0x02;
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

	/* Thermometer: temperature characteristic format */
	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
	atval[0] = 0x0E;
	atval[1] = 0xFE;
	att_put_u16(FMT_CELSIUS_UUID, &atval[2]);
	atval[4] = 0x01;
	att_put_u16(FMT_OUTSIDE_UUID, &atval[5]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 7);

	/* Thermometer: characteristic user description */
	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
	len = strlen(desc_out_temp);
	strncpy((char *) atval, desc_out_temp, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	/* Thermometer: relative humidity characteristic */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(RELATIVE_HUMIDITY_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Thermometer: relative humidity value */
	bt_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID);
	atval[0] = 0x27;
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1);

	/* Thermometer: relative humidity characteristic format */
	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
	atval[0] = 0x04;
	atval[1] = 0x00;
	att_put_u16(FMT_PERCENT_UUID, &atval[2]);
	att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]);
	att_put_u16(FMT_OUTSIDE_UUID, &atval[6]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);

	/* Thermometer: characteristic user description */
	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
	len = strlen(desc_out_hum);
	strncpy((char *) atval, desc_out_hum, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	g_assert(h - start_handle == svc_size);

	/* Add an SDP record for the above service */
	sdp_handle = attrib_create_sdp(start_handle, "Thermometer");
	if (sdp_handle)
		sdp_handles = g_slist_prepend(sdp_handles,
						GUINT_TO_POINTER(sdp_handle));
}

static void register_manuf1_service(uint16_t range[2])
{
	const char *manufacturer_name1 = "ACME Temperature Sensor";
	const char *serial1 = "237495-3282-A";
	uint16_t start_handle, h;
	const int svc_size = 5;
	uint8_t atval[256];
	bt_uuid_t uuid;
	int len;

	start_handle = attrib_db_find_avail(svc_size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		return;
	}

	DBG("start_handle=0x%04x", start_handle);

	h = start_handle;

	/* Secondary Service: Manufacturer Service */
	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
	att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

	/* Manufacturer name characteristic definition */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Manufacturer name characteristic value */
	bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
	len = strlen(manufacturer_name1);
	strncpy((char *) atval, manufacturer_name1, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	/* Manufacturer serial number characteristic */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Manufacturer serial number characteristic value */
	bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
	len = strlen(serial1);
	strncpy((char *) atval, serial1, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	g_assert(h - start_handle == svc_size);

	range[0] = start_handle;
	range[1] = start_handle + svc_size - 1;
}

static void register_manuf2_service(uint16_t range[2])
{
	const char *manufacturer_name2 = "ACME Weighing Scales";
	const char *serial2 = "11267-2327A00239";
	uint16_t start_handle, h;
	const int svc_size = 5;
	uint8_t atval[256];
	bt_uuid_t uuid;
	int len;

	start_handle = attrib_db_find_avail(svc_size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		return;
	}

	DBG("start_handle=0x%04x", start_handle);

	h = start_handle;

	/* Secondary Service: Manufacturer Service */
	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
	att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

	/* Manufacturer name characteristic definition */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Manufacturer name attribute */
	bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
	len = strlen(manufacturer_name2);
	strncpy((char *) atval, manufacturer_name2, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	/* Characteristic: serial number */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Serial number characteristic value */
	bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
	len = strlen(serial2);
	strncpy((char *) atval, serial2, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	g_assert(h - start_handle == svc_size);

	range[0] = start_handle;
	range[1] = start_handle + svc_size - 1;
}

static void register_vendor_service(uint16_t range[2])
{
	uint16_t start_handle, h;
	const int svc_size = 3;
	uint8_t atval[256];
	bt_uuid_t uuid;

	start_handle = attrib_db_find_avail(svc_size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		return;
	}

	DBG("start_handle=0x%04x", start_handle);

	h = start_handle;

	/* Secondary Service: Vendor Specific Service */
	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
	att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[0]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

	/* Vendor Specific Type characteristic definition */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	att_put_u16(VENDOR_SPECIFIC_TYPE_UUID, &atval[3]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

	/* Vendor Specific Type characteristic value */
	bt_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID);
	atval[0] = 0x56;
	atval[1] = 0x65;
	atval[2] = 0x6E;
	atval[3] = 0x64;
	atval[4] = 0x6F;
	atval[5] = 0x72;
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);

	g_assert(h - start_handle == svc_size);

	range[0] = start_handle;
	range[1] = start_handle + svc_size - 1;
}

static void register_weight_service(const uint16_t vendor[2])
{
	const char *desc_weight = "Rucksack Weight";
	const uint128_t char_weight_uuid_btorder = {
		.data = { 0x80, 0x88, 0xF2, 0x18, 0x90, 0x2C, 0x45, 0x0B,
			  0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25, 0xE9 } };
	const uint128_t prim_weight_uuid_btorder = {
		.data = { 0x4F, 0x0A, 0xC0, 0x96, 0x35, 0xD4, 0x49, 0x11,
			  0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE, 0xFE } };
	uint128_t char_weight_uuid;
	uint16_t start_handle, h;
	const int svc_size = 6;
	uint32_t sdp_handle;
	uint8_t atval[256];
	bt_uuid_t uuid;
	int len;

	btoh128(&char_weight_uuid_btorder, &char_weight_uuid);

	start_handle = attrib_db_find_avail(svc_size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		return;
	}

	DBG("start_handle=0x%04x, vendor=0x%04x-0x%04x", start_handle,
							vendor[0], vendor[1]);

	h = start_handle;

	/* Weight service: primary service definition */
	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
	memcpy(atval, &prim_weight_uuid_btorder, 16);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 16);

	if (vendor[0] && vendor[1]) {
		/* Weight: include */
		bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
		att_put_u16(vendor[0], &atval[0]);
		att_put_u16(vendor[1], &atval[2]);
		att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]);
		attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval,
									6);
	}

	/* Weight: characteristic */
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = ATT_CHAR_PROPER_READ;
	att_put_u16(h + 1, &atval[1]);
	memcpy(&atval[3], &char_weight_uuid_btorder, 16);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 19);

	/* Weight: characteristic value */
	bt_uuid128_create(&uuid, char_weight_uuid);
	atval[0] = 0x82;
	atval[1] = 0x55;
	atval[2] = 0x00;
	atval[3] = 0x00;
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4);

	/* Weight: characteristic format */
	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
	atval[0] = 0x08;
	atval[1] = 0xFD;
	att_put_u16(FMT_KILOGRAM_UUID, &atval[2]);
	att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]);
	att_put_u16(FMT_HANGING_UUID, &atval[6]);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);

	/* Weight: characteristic user description */
	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
	len = strlen(desc_weight);
	strncpy((char *) atval, desc_weight, len);
	attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);

	g_assert(h - start_handle == svc_size);

	/* Add an SDP record for the above service */
	sdp_handle = attrib_create_sdp(start_handle, "Weight Service");
	if (sdp_handle)
		sdp_handles = g_slist_prepend(sdp_handles,
						GUINT_TO_POINTER(sdp_handle));
}

static int gatt_example_init(void)
{
	uint16_t manuf1_range[2] = {0, 0}, manuf2_range[2] = {0, 0};
	uint16_t vendor_range[2] = {0, 0};

	if (!main_opts.attrib_server) {
		DBG("Attribute server is disabled");
		return -1;
	}

	if (!register_battery_service()) {
		DBG("Battery service could not be registered");
		return -EIO;
	}

	register_manuf1_service(manuf1_range);
	register_manuf2_service(manuf2_range);
	register_termometer_service(manuf1_range, manuf2_range);
	register_vendor_service(vendor_range);
	register_weight_service(vendor_range);

	return 0;
}

static void gatt_example_exit(void)
{
	if (!main_opts.attrib_server)
		return;

	while (sdp_handles) {
		uint32_t handle = GPOINTER_TO_UINT(sdp_handles->data);

		attrib_free_sdp(handle);
		sdp_handles = g_slist_remove(sdp_handles, sdp_handles->data);
	}
}

BLUETOOTH_PLUGIN_DEFINE(gatt_example, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW,
					gatt_example_init, gatt_example_exit)
