/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Texas Instruments, Inc.
 *
 *  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 <glib.h>

#include "src/log.h"

#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/uuid.h"

#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/shared/att.h"
#include "src/shared/gatt-db.h"

#include "attrib/gattrib.h"
#include "attrib/att.h"
#include "attrib/gatt.h"

#include "profiles/deviceinfo/dis.h"

#define DIS_UUID16	0x180a
#define PNP_ID_SIZE	7

struct bt_dis {
	int			ref_count;
	uint16_t		handle;
	uint8_t			source;
	uint16_t		vendor;
	uint16_t		product;
	uint16_t		version;
	GAttrib			*attrib;	/* GATT connection */
	struct gatt_primary	*primary;	/* Primary details */
	bt_dis_notify		notify;
	void			*notify_data;
	struct queue		*gatt_op;
};

struct characteristic {
	struct gatt_char	attr;	/* Characteristic */
	struct bt_dis		*d;	/* deviceinfo where the char belongs */
};

struct gatt_request {
	unsigned int id;
	struct bt_dis *dis;
	void *user_data;
};

static void destroy_gatt_req(struct gatt_request *req)
{
	queue_remove(req->dis->gatt_op, req);
	bt_dis_unref(req->dis);
	free(req);
}

static void dis_free(struct bt_dis *dis)
{
	bt_dis_detach(dis);

	g_free(dis->primary);
	queue_destroy(dis->gatt_op, (void *) destroy_gatt_req);
	g_free(dis);
}

static void foreach_dis_char(struct gatt_db_attribute *attr, void *user_data)
{
	struct bt_dis *dis = user_data;
	bt_uuid_t pnpid_uuid, uuid;
	uint16_t value_handle;

	/* Ignore if there are multiple instances */
	if (dis->handle)
		return;

	if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL, NULL, &uuid))
		return;

	/* Find PNPID characteristic's value handle */
	bt_string_to_uuid(&pnpid_uuid, PNPID_UUID);
	if (bt_uuid_cmp(&pnpid_uuid, &uuid) == 0)
		dis->handle = value_handle;
}

static void foreach_dis_service(struct gatt_db_attribute *attr, void *user_data)
{
	struct bt_dis *dis = user_data;

	/* Ignore if there are multiple instances */
	if (dis->handle)
		return;

	gatt_db_service_foreach_char(attr, foreach_dis_char, dis);
}

struct bt_dis *bt_dis_new(struct gatt_db *db)
{
	struct bt_dis *dis;

	dis = g_try_new0(struct bt_dis, 1);
	if (!dis)
		return NULL;

	dis->gatt_op = queue_new();

	if (db) {
		bt_uuid_t uuid;

		/* Handle the DIS service */
		bt_uuid16_create(&uuid, DIS_UUID16);
		gatt_db_foreach_service(db, &uuid, foreach_dis_service, dis);
		if (!dis->handle) {
			dis_free(dis);
			return NULL;
		}
	}

	return bt_dis_ref(dis);
}

struct bt_dis *bt_dis_new_primary(void *primary)
{
	struct bt_dis *dis;

	dis = g_try_new0(struct bt_dis, 1);
	if (!dis)
		return NULL;

	dis->gatt_op = queue_new();

	if (primary)
		dis->primary = g_memdup(primary, sizeof(*dis->primary));

	return bt_dis_ref(dis);
}

struct bt_dis *bt_dis_ref(struct bt_dis *dis)
{
	if (!dis)
		return NULL;

	__sync_fetch_and_add(&dis->ref_count, 1);

	return dis;
}

void bt_dis_unref(struct bt_dis *dis)
{
	if (!dis)
		return;

	if (__sync_sub_and_fetch(&dis->ref_count, 1))
		return;

	dis_free(dis);
}

static struct gatt_request *create_request(struct bt_dis *dis,
							void *user_data)
{
	struct gatt_request *req;

	req = new0(struct gatt_request, 1);
	req->user_data = user_data;
	req->dis = bt_dis_ref(dis);

	return req;
}

static bool set_and_store_gatt_req(struct bt_dis *dis,
						struct gatt_request *req,
						unsigned int id)
{
	req->id = id;
	return queue_push_head(dis->gatt_op, req);
}

static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct gatt_request *req = user_data;
	struct bt_dis *dis = req->user_data;
	uint8_t value[PNP_ID_SIZE];
	ssize_t vlen;

	destroy_gatt_req(req);

	if (status != 0) {
		error("Error reading PNP_ID value: %s", att_ecode2str(status));
		return;
	}

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

	if (vlen < 7) {
		error("Error reading PNP_ID: Invalid pdu length received");
		return;
	}

	dis->source = value[0];
	dis->vendor = get_le16(&value[1]);
	dis->product = get_le16(&value[3]);
	dis->version = get_le16(&value[5]);

	DBG("source: 0x%02X vendor: 0x%04X product: 0x%04X version: 0x%04X",
			dis->source, dis->vendor, dis->product, dis->version);

	if (dis->notify)
		dis->notify(dis->source, dis->vendor, dis->product,
						dis->version, dis->notify_data);
}

static void read_char(struct bt_dis *dis, GAttrib *attrib, uint16_t handle,
				GAttribResultFunc func, gpointer user_data)
{
	struct gatt_request *req;
	unsigned int id;

	req = create_request(dis, user_data);

	id = gatt_read_char(attrib, handle, func, req);

	if (set_and_store_gatt_req(dis, req, id))
		return;

	error("dis: Could not read characteristic");
	g_attrib_cancel(attrib, id);
	free(req);
}

static void discover_char(struct bt_dis *dis, GAttrib *attrib,
						uint16_t start, uint16_t end,
						bt_uuid_t *uuid, gatt_cb_t func,
						gpointer user_data)
{
	struct gatt_request *req;
	unsigned int id;

	req = create_request(dis, user_data);

	id = gatt_discover_char(attrib, start, end, uuid, func, req);

	if (set_and_store_gatt_req(dis, req, id))
		return;

	error("dis: Could not send discover characteristic");
	g_attrib_cancel(attrib, id);
	free(req);
}

static void configure_deviceinfo_cb(uint8_t status, GSList *characteristics,
								void *user_data)
{
	struct gatt_request *req = user_data;
	struct bt_dis *d = req->user_data;
	GSList *l;

	destroy_gatt_req(req);

	if (status != 0) {
		error("Discover deviceinfo characteristics: %s",
							att_ecode2str(status));
		return;
	}

	for (l = characteristics; l; l = l->next) {
		struct gatt_char *c = l->data;

		if (strcmp(c->uuid, PNPID_UUID) == 0) {
			d->handle = c->value_handle;
			read_char(d, d->attrib, d->handle, read_pnpid_cb, d);
			break;
		}
	}
}

bool bt_dis_attach(struct bt_dis *dis, void *attrib)
{
	struct gatt_primary *primary = dis->primary;

	if (dis->attrib)
		return false;

	dis->attrib = g_attrib_ref(attrib);

	if (!dis->handle)
		discover_char(dis, dis->attrib, primary->range.start,
						primary->range.end, NULL,
						configure_deviceinfo_cb, dis);
	else
		read_char(dis, attrib, dis->handle, read_pnpid_cb, dis);

	return true;
}

static void cancel_gatt_req(struct gatt_request *req)
{
	if (g_attrib_cancel(req->dis->attrib, req->id))
		destroy_gatt_req(req);
}

void bt_dis_detach(struct bt_dis *dis)
{
	if (!dis->attrib)
		return;

	queue_foreach(dis->gatt_op, (void *) cancel_gatt_req, NULL);
	g_attrib_unref(dis->attrib);
	dis->attrib = NULL;
}

bool bt_dis_set_notification(struct bt_dis *dis, bt_dis_notify func,
							void *user_data)
{
	if (!dis)
		return false;

	dis->notify = func;
	dis->notify_data = user_data;

	return true;
}
