/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2008  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 <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/param.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/sdp.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus.h>

#include "hcid.h"
#include "dbus-common.h"
#include "adapter.h"
#include "dbus-hci.h"
#include "dbus-error.h"
#include "error.h"
#include "dbus-test.h"

#define L2INFO_TIMEOUT (2 * 1000)

enum {
	AUDIT_STATE_MTU = 0,
	AUDIT_STATE_FEATURES
};

struct audit {
	bdaddr_t peer;
	bdaddr_t local;

	/* We need to store the path instead of a pointer to the data
	 * because by the time the audit is processed the adapter
	 * might have gotten removed. Storing only the path allows us to
	 * detect this scenario */
	char adapter_path[PATH_MAX];

	char *requestor;
	DBusConnection *conn;

	GIOChannel *io;
	guint io_id;

	guint timeout;

	int state;

	uint16_t mtu_result;
	uint16_t mtu;

	uint16_t mask_result;
	uint32_t mask;
};

static GSList *audits = NULL;

static gboolean l2raw_connect_complete(GIOChannel *io, GIOCondition cond,
					struct audit *audit);

static struct audit *audit_new(DBusConnection *conn, DBusMessage *msg,
				bdaddr_t *peer, bdaddr_t *local)
{
	struct audit *audit;
	const char *path;
	const char *requestor;

	path = dbus_message_get_path(msg);
	requestor = dbus_message_get_sender(msg);

	audit = g_new0(struct audit, 1);

	audit->requestor = g_strdup(requestor);

	bacpy(&audit->peer, peer);
	bacpy(&audit->local, local);
	strncpy(audit->adapter_path, path, sizeof(audit->adapter_path) - 1);
	audit->conn = dbus_connection_ref(conn);

	return audit;
}

static void audit_free(struct audit *audit)
{
	g_free(audit->requestor);
	dbus_connection_unref(audit->conn);
	g_free(audit);
}

static void send_audit_status(struct audit *audit, const char *name)
{
	char addr[18], *addr_ptr = addr;

	ba2str(&audit->peer, addr);

	dbus_connection_emit_signal(audit->conn, audit->adapter_path,
					TEST_INTERFACE, name,
					DBUS_TYPE_STRING, &addr_ptr,
					DBUS_TYPE_INVALID);
}

static void audit_requestor_exited(const char *name, struct audit *audit)
{
	debug("AuditRemoteDevice requestor %s exited", name);
	audits = g_slist_remove(audits, audit);
	if (audit->io) {
		struct adapter *adapter = NULL;

		send_audit_status(audit, "AuditRemoteDeviceComplete");

		dbus_connection_get_object_user_data(audit->conn,
							audit->adapter_path,
							(void *) &adapter);
		if (adapter)
			bacpy(&adapter->agents_disabled, BDADDR_ANY);

		g_io_channel_close(audit->io);
	}
	if (audit->timeout)
		g_source_remove(audit->timeout);
	audit_free(audit);
}

int audit_addr_cmp(const void *a, const void *b)
{
	const struct audit *audit = a;
	const bdaddr_t *addr = b;

	return bacmp(&audit->peer, addr);
}

static gboolean audit_in_progress(void)
{
	GSList *l;

	for (l = audits; l != NULL; l = l->next) {
		struct audit *audit = l->data;
		if (audit->io)
			return TRUE;
	}

	return FALSE;
}

static gboolean l2raw_input_timer(struct audit *audit)
{
	error("l2raw_input_timer: Timed out while waiting for input");

	send_audit_status(audit, "AuditRemoteDeviceComplete");

	g_io_channel_close(audit->io);
	audits = g_slist_remove(audits, audit);
	name_listener_remove(audit->conn, audit->requestor,
				(name_cb_t) audit_requestor_exited, audit);
	audit_free(audit);

	return FALSE;
}

static void handle_mtu_response(struct audit *audit, const l2cap_info_rsp *rsp)
{
	audit->mtu_result = btohs(rsp->result);

	switch (audit->mtu_result) {
	case 0x0000:
		audit->mtu = btohs(bt_get_unaligned((uint16_t *) rsp->data));
		debug("Connectionless MTU size is %d", audit->mtu);
		break;
	case 0x0001:
		debug("Connectionless MTU is not supported");
		break;
	}
}

static void handle_features_response(struct audit *audit, const l2cap_info_rsp *rsp)
{
	audit->mask_result = btohs(rsp->result);

	switch (audit->mask_result) {
	case 0x0000:
		audit->mask = btohl(bt_get_unaligned((uint32_t *) rsp->data));
		debug("Extended feature mask is 0x%04x", audit->mask);
		if (audit->mask & 0x01)
			debug("  Flow control mode");
		if (audit->mask & 0x02)
			debug("  Retransmission mode");
		if (audit->mask & 0x04)
			debug("  Bi-directional QoS");
		break;
	case 0x0001:
		debug("Extended feature mask is not supported");
		break;
	}
}

static gboolean l2raw_data_callback(GIOChannel *io, GIOCondition cond, struct audit *audit)
{
	unsigned char buf[48];
	l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf;
	l2cap_info_req *req = (l2cap_info_req *) (buf + L2CAP_CMD_HDR_SIZE);
	l2cap_info_rsp *rsp = (l2cap_info_rsp *) (buf + L2CAP_CMD_HDR_SIZE);
	int sk, ret, expected;

	if (cond & G_IO_NVAL) {
		g_io_channel_unref(io);
		return FALSE;
	}

	if (cond & (G_IO_ERR | G_IO_HUP))
		goto failed;

	sk = g_io_channel_unix_get_fd(io);

	memset(buf, 0, sizeof(buf));

	if (audit->state == AUDIT_STATE_MTU)
		expected = L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 2;
	else
		expected = L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 4;

	ret = recv(sk, buf, expected, 0);
	if (ret < 0) {
		error("Can't receive info response: %s (%d)", strerror(errno), errno);
		goto failed;
	}

	if (ret < L2CAP_CMD_HDR_SIZE) {
		error("Too little data for l2cap response");
		goto failed;
	}

	if (cmd->code != L2CAP_INFO_RSP)
		return TRUE;

	if (ret < L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE) {
		error("Too little data for l2cap info response");
		goto failed;
	}

	switch (audit->state) {
	case AUDIT_STATE_MTU:
		if (rsp->type != htobs(0x0001))
			return TRUE;

		if (audit->timeout) {
			g_source_remove(audit->timeout);
			audit->timeout = 0;
		}

		handle_mtu_response(audit, rsp);

		memset(buf, 0, sizeof(buf));
		cmd->code  = L2CAP_INFO_REQ;
		cmd->ident = 43;
		cmd->len   = htobs(2);
		req->type  = htobs(0x0002);

		if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) {
			error("Can't send info request:", strerror(errno), errno);
			goto failed;
		}

		audit->timeout = g_timeout_add(L2INFO_TIMEOUT, (GSourceFunc)
						l2raw_input_timer, audit);

		audit->state = AUDIT_STATE_FEATURES;

		return TRUE;

	case AUDIT_STATE_FEATURES:
		if (rsp->type != htobs(0x0002))
			return TRUE;

		if (audit->timeout) {
			g_source_remove(audit->timeout);
			audit->timeout = 0;
		}

		handle_features_response(audit, rsp);
		break;
	}

	write_l2cap_info(&audit->local, &audit->peer,
				audit->mtu_result, audit->mtu,
				audit->mask_result, audit->mask);

failed:
	if (audit->timeout) {
		g_source_remove(audit->timeout);
		audit->timeout = 0;
	}

	send_audit_status(audit, "AuditRemoteDeviceComplete");

	g_io_channel_close(io);
	g_io_channel_unref(io);
	audits = g_slist_remove(audits, audit);
	name_listener_remove(audit->conn, audit->requestor,
				(name_cb_t) audit_requestor_exited, audit);

	process_audits_list(audit->adapter_path);

	audit_free(audit);

	return FALSE;
}

static gboolean l2raw_connect_complete(GIOChannel *io, GIOCondition cond, struct audit *audit)
{
	unsigned char buf[48];
	l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf;
	l2cap_info_req *req = (l2cap_info_req *) (buf + L2CAP_CMD_HDR_SIZE);
	socklen_t len;
	int sk, ret;
	struct adapter *adapter = NULL;

	if (cond & G_IO_NVAL) {
		g_io_channel_unref(io);
		return FALSE;
	}

	dbus_connection_get_object_user_data(audit->conn, audit->adapter_path,
						(void *) &adapter);
	if (adapter)
		bacpy(&adapter->agents_disabled, BDADDR_ANY);

	if (cond & (G_IO_ERR | G_IO_HUP)) {
		error("Error on raw l2cap socket");
		goto failed;
	}

	sk = g_io_channel_unix_get_fd(io);

	len = sizeof(ret);
	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		error("Can't get socket error: %s (%d)", strerror(errno), errno);
		goto failed;
	}

	if (ret != 0) {
		error("l2raw_connect failed: %s (%d)", strerror(ret), ret);
		goto failed;
	}

	debug("AuditRemoteDevice: connected");

	/* Send L2CAP info request */
	memset(buf, 0, sizeof(buf));
	cmd->code  = L2CAP_INFO_REQ;
	cmd->ident = 42;
	cmd->len   = htobs(2);
	req->type  = htobs(0x0001);

	if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) {
		error("Can't send info request: %s (%d)", strerror(errno), errno);
		goto failed;
	}

	audit->timeout = g_timeout_add(L2INFO_TIMEOUT, (GSourceFunc)
			l2raw_input_timer, audit);

	audit->io_id = g_io_add_watch(audit->io,
					G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
					(GIOFunc) l2raw_data_callback, audit);

	return FALSE;

failed:
	send_audit_status(audit, "AuditRemoteDeviceFailed");

	g_io_channel_close(io);
	g_io_channel_unref(io);
	audits = g_slist_remove(audits, audit);
	name_listener_remove(audit->conn, audit->requestor,
				(name_cb_t) audit_requestor_exited, audit);
	audit_free(audit);

	return FALSE;
}

static DBusHandlerResult audit_remote_device(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	DBusError err;
	bdaddr_t peer, local;
	const char *address;
	struct audit *audit;
	struct adapter *adapter = data;
	gboolean queue;

	dbus_error_init(&err);
	dbus_message_get_args(msg, &err,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);
	if (dbus_error_is_set(&err)) {
		error("Can't extract message arguments:%s", err.message);
		dbus_error_free(&err);
		return error_invalid_arguments(conn, msg, NULL);
	}

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg, NULL);

	str2ba(address, &peer);
	str2ba(adapter->address, &local);

	pending_remote_name_cancel(adapter);

	if (adapter->bonding)
		return error_bonding_in_progress(conn, msg);

	if (g_slist_find_custom(adapter->pin_reqs, &peer, pin_req_cmp))
		return error_bonding_in_progress(conn, msg);

	if (!read_l2cap_info(&local, &peer, NULL, NULL, NULL, NULL))
		return error_audit_already_exists(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	/* Just return if an audit for the same device is already queued */
	if (g_slist_find_custom(audits, &peer, audit_addr_cmp))
		return send_message_and_unref(conn, reply);

	if (adapter->discov_active || (adapter->pdiscov_active && !adapter->pinq_idle))
		queue = TRUE;
	else
		queue = audit_in_progress();

	audit = audit_new(conn, msg, &peer, &local);
	if (!audit) {
		dbus_message_unref(reply);
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	}

	if (!queue) {
		int sk;

		sk = l2raw_connect(adapter->address, &peer);
		if (sk < 0) {
			audit_free(audit);
			dbus_message_unref(reply);
			return error_connection_attempt_failed(conn, msg, 0);
		}

		bacpy(&adapter->agents_disabled, &peer);

		audit->io = g_io_channel_unix_new(sk);
		audit->io_id = g_io_add_watch(audit->io,
						G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
						(GIOFunc) l2raw_connect_complete, audit);
	}

	name_listener_add(conn, dbus_message_get_sender(msg),
				(name_cb_t) audit_requestor_exited, audit);

	audits = g_slist_append(audits, audit);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult cancel_audit_remote_device(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	DBusError err;
	const char *address;
	bdaddr_t peer, local;
	GSList *l;
	struct audit *audit;

	dbus_error_init(&err);
	dbus_message_get_args(msg, &err,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);
	if (dbus_error_is_set(&err)) {
		error("Can't extract message arguments:%s", err.message);
		dbus_error_free(&err);
		return error_invalid_arguments(conn, msg, NULL);
	}

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg, NULL);

	str2ba(address, &peer);
	str2ba(adapter->address, &local);

	l = g_slist_find_custom(audits, &peer, audit_addr_cmp);
	if (!l)
		return error_not_in_progress(conn, msg, "Audit not in progress");

	audit = l->data;

	/* Check that the audit wasn't for another adapter */
	if (bacmp(&audit->local, &local))
		return error_not_in_progress(conn, msg, "Audit not in progress");

	if (strcmp(audit->requestor, dbus_message_get_sender(msg)))
		return error_not_authorized(conn, msg);

	if (audit->io) {
		send_audit_status(audit, "AuditRemoteDeviceComplete");
		bacpy(&adapter->agents_disabled, BDADDR_ANY);
		g_io_channel_close(audit->io);
	}
	if (audit->timeout)
		g_source_remove(audit->timeout);

	audits = g_slist_remove(audits, audit);
	name_listener_remove(audit->conn, audit->requestor,
				(name_cb_t) audit_requestor_exited, audit);
	audit_free(audit);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_l2cap_feature_mask(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	DBusError err;
	const char *address;
	bdaddr_t peer, local;
	uint32_t mask;
	uint16_t result;

	dbus_error_init(&err);
	dbus_message_get_args(msg, &err,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);
	if (dbus_error_is_set(&err)) {
		error("Can't extract message arguments:%s", err.message);
		dbus_error_free(&err);
		return error_invalid_arguments(conn, msg, NULL);
	}

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg, NULL);

	str2ba(address, &peer);
	str2ba(adapter->address, &local);

	if (read_l2cap_info(&local, &peer, NULL, NULL, &result, &mask) < 0)
		return error_not_available(conn, msg);

	if (result)
		return error_not_supported(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &mask,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_l2cap_mtu_size(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	DBusError err;
	const char *address;
	bdaddr_t peer, local;
	uint16_t result, mtu;

	dbus_error_init(&err);
	dbus_message_get_args(msg, &err,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);
	if (dbus_error_is_set(&err)) {
		error("Can't extract message arguments:%s", err.message);
		dbus_error_free(&err);
		return error_invalid_arguments(conn, msg, NULL);
	}

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg, NULL);

	str2ba(address, &peer);
	str2ba(adapter->address, &local);

	if (read_l2cap_info(&local, &peer, &result, &mtu, NULL, NULL) < 0)
		return error_not_available(conn, msg);

	if (result)
		return error_not_supported(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply, DBUS_TYPE_UINT16, &mtu,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusMethodVTable test_methods[] = {
	{ "AuditRemoteDevice",		audit_remote_device,
		"s",	""	},
	{ "CancelAuditRemoteDevice",	cancel_audit_remote_device,
		"s",	""	},
	{ "GetL2capFeatureMask",	get_l2cap_feature_mask,
		"s",	"u"	},
	{ "GetL2capMtuSize",		get_l2cap_mtu_size,
		"s",	"q"	},
	{ NULL, NULL, NULL, NULL }
};

dbus_bool_t test_init(DBusConnection *conn, const char *path)
{
	if (!hcid_dbus_use_experimental())
		return TRUE;

	return dbus_connection_register_interface(conn, path, TEST_INTERFACE,
							test_methods,
							NULL, NULL);
}

void process_audits_list(const char *adapter_path)
{
	GSList *l, *next;

	for (l = audits; l != NULL; l = next) {
		struct adapter *adapter;
		struct audit *audit;
		int sk;

		audit = l->data;
		next = l->next;

		if (strcmp(adapter_path, audit->adapter_path))
			continue;

		if (audit->io)
			return;

		adapter = NULL;

		dbus_connection_get_object_user_data(audit->conn,
							audit->adapter_path,
							(void *) &adapter);

		if (!adapter) {
			audits = g_slist_remove(audits, audit);
			name_listener_remove(audit->conn, audit->requestor,
					(name_cb_t) audit_requestor_exited, audit);
			audit_free(audit);
			continue;
		}

		if (adapter->discov_active || (adapter->pdiscov_active
					&& !adapter->pinq_idle))
			continue;

		sk = l2raw_connect(adapter->address, &audit->peer);
		if (sk < 0) {
			send_audit_status(audit, "AuditRemoteDeviceFailed");
			audits = g_slist_remove(audits, audit);
			name_listener_remove(audit->conn, audit->requestor,
					(name_cb_t) audit_requestor_exited, audit);
			audit_free(audit);
			continue;
		}

		bacpy(&adapter->agents_disabled, &audit->peer);

		audit->io = g_io_channel_unix_new(sk);
		audit->io_id = g_io_add_watch(audit->io,
						G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
						(GIOFunc) l2raw_connect_complete, audit);
		return;
	}
}
