/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  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 <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>

#include <glib.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "hcid.h"
#include "dbus-common.h"
#include "dbus-hci.h"
#include "dbus-adapter.h"
#include "dbus-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);
	}

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

	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);
	}

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

	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);
	}

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

	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);
	}

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

	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;
	}
}
