/*
 *
 *  OBEX Client
 *
 *  Copyright (C) 2012 Intel Corporation
 *
 *
 *  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 <stdlib.h>
#include <errno.h>
#include <inttypes.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/rfcomm.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"

#include "gdbus/gdbus.h"
#include "btio/btio.h"

#include "obexd/src/log.h"
#include "transport.h"
#include "bluetooth.h"

#define BT_RX_MTU 32767
#define BT_TX_MTU 32767

#define OBC_BT_ERROR obc_bt_error_quark()

struct bluetooth_session {
	guint id;
	bdaddr_t src;
	bdaddr_t dst;
	uint16_t port;
	sdp_session_t *sdp;
	sdp_record_t *sdp_record;
	GIOChannel *io;
	char *service;
	obc_transport_func func;
	void *user_data;
};

static GSList *sessions = NULL;

static GQuark obc_bt_error_quark(void)
{
	return g_quark_from_static_string("obc-bluetooth-error-quark");
}

static void session_destroy(struct bluetooth_session *session)
{
	DBG("%p", session);

	if (g_slist_find(sessions, session) == NULL)
		return;

	sessions = g_slist_remove(sessions, session);

	if (session->io != NULL) {
		g_io_channel_shutdown(session->io, TRUE, NULL);
		g_io_channel_unref(session->io);
	}

	if (session->sdp)
		sdp_close(session->sdp);

	if (session->sdp_record)
		sdp_record_free(session->sdp_record);

	g_free(session->service);
	g_free(session);
}

static void transport_callback(GIOChannel *io, GError *err, gpointer user_data)
{
	struct bluetooth_session *session = user_data;

	DBG("");

	if (session->func)
		session->func(io, err, session->user_data);

	if (err != NULL)
		session_destroy(session);
}

static GIOChannel *transport_connect(const bdaddr_t *src, const bdaddr_t *dst,
					uint16_t port, BtIOConnect function,
					gpointer user_data)
{
	GIOChannel *io;
	GError *err = NULL;

	DBG("port %u", port);

	if (port > 31) {
		io = bt_io_connect(function, user_data,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_PSM, port,
				BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
				BT_IO_OPT_OMTU, BT_TX_MTU,
				BT_IO_OPT_IMTU, BT_RX_MTU,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	} else {
		io = bt_io_connect(function, user_data,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_CHANNEL, port,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	}

	if (io != NULL)
		return io;

	error("%s", err->message);
	g_error_free(err);
	return NULL;
}

static void search_callback(uint8_t type, uint16_t status,
			uint8_t *rsp, size_t size, void *user_data)
{
	struct bluetooth_session *session = user_data;
	unsigned int scanned, bytesleft = size;
	int seqlen = 0;
	uint8_t dataType;
	uint16_t port = 0;
	GError *gerr = NULL;

	if (status || type != SDP_SVC_SEARCH_ATTR_RSP)
		goto failed;

	scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen);
	if (!scanned || !seqlen)
		goto failed;

	rsp += scanned;
	bytesleft -= scanned;
	do {
		sdp_record_t *rec;
		sdp_list_t *protos;
		sdp_data_t *data;
		int recsize, ch = -1;

		recsize = 0;
		rec = sdp_extract_pdu(rsp, bytesleft, &recsize);
		if (!rec)
			break;

		if (!recsize) {
			sdp_record_free(rec);
			break;
		}

		if (!sdp_get_access_protos(rec, &protos)) {
			ch = sdp_get_proto_port(protos, RFCOMM_UUID);
			sdp_list_foreach(protos,
					(sdp_list_func_t) sdp_list_free, NULL);
			sdp_list_free(protos, NULL);
			protos = NULL;
		}

		data = sdp_data_get(rec, 0x0200);
		/* PSM must be odd and lsb of upper byte must be 0 */
		if (data != NULL && (data->val.uint16 & 0x0101) == 0x0001)
			ch = data->val.uint16;

		/* Cache the sdp record associated with the service that we
		 * attempt to connect. This allows reading its application
		 * specific service attributes. */
		if (ch > 0) {
			port = ch;
			session->sdp_record = rec;
			break;
		}

		sdp_record_free(rec);

		scanned += recsize;
		rsp += recsize;
		bytesleft -= recsize;
	} while (scanned < size && bytesleft > 0);

	if (port == 0)
		goto failed;

	session->port = port;

	g_io_channel_set_close_on_unref(session->io, FALSE);
	g_io_channel_unref(session->io);

	session->io = transport_connect(&session->src, &session->dst, port,
						transport_callback, session);
	if (session->io != NULL) {
		sdp_close(session->sdp);
		session->sdp = NULL;
		return;
	}

failed:
	if (session->io != NULL) {
		g_io_channel_shutdown(session->io, TRUE, NULL);
		g_io_channel_unref(session->io);
		session->io = NULL;
	}

	g_set_error(&gerr, OBC_BT_ERROR, -EIO,
					"Unable to find service record");
	if (session->func)
		session->func(session->io, gerr, session->user_data);

	g_clear_error(&gerr);

	session_destroy(session);
}

static gboolean process_callback(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct bluetooth_session *session = user_data;

	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
		return FALSE;

	if (sdp_process(session->sdp) < 0)
		return FALSE;

	return TRUE;
}

static int bt_string2uuid(uuid_t *uuid, const char *string)
{
	uint32_t data0, data4;
	uint16_t data1, data2, data3, data5;

	if (sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
				&data0, &data1, &data2, &data3, &data4, &data5) == 6) {
		uint8_t val[16];

		data0 = g_htonl(data0);
		data1 = g_htons(data1);
		data2 = g_htons(data2);
		data3 = g_htons(data3);
		data4 = g_htonl(data4);
		data5 = g_htons(data5);

		memcpy(&val[0], &data0, 4);
		memcpy(&val[4], &data1, 2);
		memcpy(&val[6], &data2, 2);
		memcpy(&val[8], &data3, 2);
		memcpy(&val[10], &data4, 4);
		memcpy(&val[14], &data5, 2);

		sdp_uuid128_create(uuid, val);

		return 0;
	}

	return -EINVAL;
}

static gboolean service_callback(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct bluetooth_session *session = user_data;
	sdp_list_t *search, *attrid;
	uint32_t range = 0x0000ffff;
	GError *gerr = NULL;
	uuid_t uuid;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & G_IO_ERR)
		goto failed;

	if (sdp_set_notify(session->sdp, search_callback, session) < 0)
		goto failed;

	if (bt_string2uuid(&uuid, session->service) < 0)
		goto failed;

	search = sdp_list_append(NULL, &uuid);
	attrid = sdp_list_append(NULL, &range);

	if (sdp_service_search_attr_async(session->sdp,
				search, SDP_ATTR_REQ_RANGE, attrid) < 0) {
		sdp_list_free(attrid, NULL);
		sdp_list_free(search, NULL);
		goto failed;
	}

	sdp_list_free(attrid, NULL);
	sdp_list_free(search, NULL);

	g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
						process_callback, session);

	return FALSE;

failed:
	g_io_channel_shutdown(session->io, TRUE, NULL);
	g_io_channel_unref(session->io);
	session->io = NULL;

	g_set_error(&gerr, OBC_BT_ERROR, -EIO,
					"Unable to find service record");
	if (session->func)
		session->func(session->io, gerr, session->user_data);
	g_clear_error(&gerr);

	session_destroy(session);
	return FALSE;
}

static sdp_session_t *service_connect(const bdaddr_t *src, const bdaddr_t *dst,
					GIOFunc function, gpointer user_data)
{
	struct bluetooth_session *session = user_data;
	sdp_session_t *sdp;
	GIOChannel *io;

	DBG("");

	sdp = sdp_connect(src, dst, SDP_NON_BLOCKING);
	if (sdp == NULL)
		return NULL;

	io = g_io_channel_unix_new(sdp_get_socket(sdp));
	if (io == NULL) {
		sdp_close(sdp);
		return NULL;
	}

	g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
							function, user_data);

	session->io = io;

	return sdp;
}

static int session_connect(struct bluetooth_session *session)
{
	int err;

	DBG("session %p", session);

	if (session->port > 0) {
		session->io = transport_connect(&session->src, &session->dst,
							session->port,
							transport_callback,
							session);
		err = (session->io == NULL) ? -EINVAL : 0;
	} else {
		session->sdp = service_connect(&session->src, &session->dst,
						service_callback, session);
		err = (session->sdp == NULL) ? -ENOMEM : 0;
	}

	return err;
}

static guint bluetooth_connect(const char *source, const char *destination,
				const char *service, uint16_t port,
				obc_transport_func func, void *user_data)
{
	struct bluetooth_session *session;
	static guint id = 0;

	DBG("src %s dest %s service %s port %u",
				source, destination, service, port);

	if (destination == NULL)
		return 0;

	session = g_try_malloc0(sizeof(*session));
	if (session == NULL)
		return 0;

	session->id = ++id;
	session->func = func;
	session->port = port;
	session->user_data = user_data;

	str2ba(destination, &session->dst);
	str2ba(source, &session->src);

	if (session_connect(session) < 0) {
		g_free(session);
		return 0;
	}

	session->service = g_strdup(service);
	sessions = g_slist_prepend(sessions, session);

	return session->id;
}

static void bluetooth_disconnect(guint id)
{
	GSList *l;

	DBG("");

	for (l = sessions; l; l = l->next) {
		struct bluetooth_session *session = l->data;

		if (session->id == id) {
			session_destroy(session);
			return;
		}
	}
}

static int bluetooth_getpacketopt(GIOChannel *io, int *tx_mtu, int *rx_mtu)
{
	int sk = g_io_channel_unix_get_fd(io);
	int type;
	uint16_t omtu = BT_TX_MTU;
	uint16_t imtu = BT_RX_MTU;
	socklen_t len = sizeof(int);

	DBG("");

	if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
		return -errno;

	if (type != SOCK_SEQPACKET)
		return -EINVAL;

	if (!bt_io_get(io, NULL, BT_IO_OPT_OMTU, &omtu,
						BT_IO_OPT_IMTU, &imtu,
						BT_IO_OPT_INVALID))
		return -EINVAL;

	if (tx_mtu)
		*tx_mtu = omtu;

	if (rx_mtu)
		*rx_mtu = imtu;

	return 0;
}

static const void *bluetooth_getattribute(guint id, int attribute_id)
{
	GSList *l;
	sdp_data_t *data;

	for (l = sessions; l; l = l->next) {
		struct bluetooth_session *session = l->data;

		if (session->id != id)
			continue;

		if (session->sdp_record == NULL)
			break;

		/* Read version since UUID is already known */
		if (attribute_id == SDP_ATTR_PFILE_DESC_LIST) {
			sdp_list_t *descs;
			void *ret = NULL;

			if (sdp_get_profile_descs(session->sdp_record,
								&descs) < 0)
				return NULL;

			if (descs && descs->data) {
				sdp_profile_desc_t *desc = descs->data;
				ret = GINT_TO_POINTER(desc->version);
			}

			sdp_list_free(descs, free);

			return ret;
		}

		data = sdp_data_get(session->sdp_record, attribute_id);
		if (!data)
			break;

		return &data->val;
	}
	return NULL;
}

static struct obc_transport bluetooth = {
	.name = "Bluetooth",
	.connect = bluetooth_connect,
	.getpacketopt = bluetooth_getpacketopt,
	.disconnect = bluetooth_disconnect,
	.getattribute = bluetooth_getattribute,
};

int bluetooth_init(void)
{
	DBG("");

	return obc_transport_register(&bluetooth);
}

void bluetooth_exit(void)
{
	DBG("");

	obc_transport_unregister(&bluetooth);
}
