/*
 *
 *  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 "hcid.h"
#include "dbus.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 = malloc(sizeof(struct audit));
	if (!audit)
		return NULL;
	memset(audit, 0, sizeof(struct audit));

	audit->requestor = strdup(requestor);
	if (!audit->requestor) {
		free(audit);
		return NULL;
	}

	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)
{
	free(audit->requestor);
	dbus_connection_unref(audit->conn);
	free(audit);
}

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

	signal = dbus_message_new_signal(audit->adapter_path, TEST_INTERFACE, name);
	if (!signal) {
		error("Failed to allocate new D-Bus message");
		return;
	}

	ba2str(&audit->peer, addr);

	dbus_message_append_args(signal, DBUS_TYPE_STRING, &addr_ptr,
					DBUS_TYPE_INVALID);

	send_message_and_unref(audit->conn, signal);
}

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_path_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_path_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 struct service_data methods[] = {
	{ "AuditRemoteDevice",		audit_remote_device		},
	{ "CancelAuditRemoteDevice",	cancel_audit_remote_device	},
	{ "GetL2capFeatureMask",	get_l2cap_feature_mask		},
	{ "GetL2capMtuSize",		get_l2cap_mtu_size		},
	{ NULL, NULL }
};

DBusHandlerResult handle_test_method(DBusConnection *conn, DBusMessage *msg, void *data)
{
	service_handler_func_t handler;

	if (!hcid_dbus_use_experimental())
		return error_unknown_method(conn, msg);

	handler = find_service_handler(methods, msg);

	if (handler)
		return handler(conn, msg, data);

	return error_unknown_method(conn, msg);
}

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