/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2006  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 <unistd.h>
#include <sys/socket.h>

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

#include <netinet/in.h>

#include "glib-ectomy.h"

#include "hcid.h"
#include "sdp.h"

struct session {
	uint16_t omtu;
	uint16_t imtu;
};

static void session_destory(gpointer data)
{
	struct session *session_data = data;

	debug("Cleanup of SDP session");

	if (session_data)
		free(session_data);
}

static gboolean session_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	unsigned char buf[672], *ptr = buf;
	sdp_pdu_hdr_t *hdr;
	gsize len;
	GIOError err;
	int sk;

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

	debug("Incoming SDP transaction");

	err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
	if (err == G_IO_ERROR_AGAIN)
		return TRUE;

	hdr = (sdp_pdu_hdr_t *) ptr;

	hdr->pdu_id = SDP_ERROR_RSP;
	hdr->plen = htons(2);
	memset(ptr + 5, 0, 2);

	sk = g_io_channel_unix_get_fd(chan);

	write(sk, ptr, 7);

	return TRUE;
}

static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	GIOChannel *io;
	struct session *session_data;
	struct sockaddr_l2 addr;
	struct l2cap_options opts;
	socklen_t optlen;
	int sk, nsk;

	debug("Incoming SDP connection");

	sk = g_io_channel_unix_get_fd(chan);

	memset(&addr, 0, sizeof(addr));
	optlen = sizeof(addr);

	nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
	if (nsk < 0) {
		error("Can't accept L2CAP connection: %s (%d)",
						strerror(errno), errno);
		return TRUE;
	}

	memset(&opts, 0, sizeof(opts));
	optlen = sizeof(opts);

	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
		error("Can't get L2CAP options: %s (%d)",
						strerror(errno), errno);
		close(nsk);
		return TRUE;
	}

	session_data = malloc(sizeof(*session_data));
	if (!session_data) {
		close(nsk);
		return TRUE;
	}

	memset(session_data, 0, sizeof(*session_data));

	session_data->omtu = opts.omtu;
	session_data->imtu = opts.imtu;

	io = g_io_channel_unix_new(nsk);

	g_io_add_watch_full(io, 0, G_IO_IN, session_event,
					session_data, session_destory);

	return TRUE;
}

int start_sdp_server(void)
{
	GIOChannel *io;
	struct sockaddr_l2 addr;
	int sk;

	info("Starting SDP server");

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (sk < 0) {
		error("Can't open L2CAP socket: %s (%d)",
						strerror(errno), errno);
		return -errno;
	}

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, BDADDR_ANY);
	addr.l2_psm = htobs(1);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		error("Can't bind L2CAP socket: %s (%d)",
						strerror(errno), errno);
		return -errno;
	}

	listen(sk, 5);

	io = g_io_channel_unix_new(sk);

	g_io_add_watch(io, G_IO_IN, connect_event, NULL);

	return 0;
}

void stop_sdp_server(void)
{
	info("Stopping SDP server");
}
