/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2010  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 <stdlib.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <net/if.h>
#include <linux/sockios.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/l2cap.h"
#include "lib/bnep.h"
#include "lib/uuid.h"

#include "src/log.h"
#include "src/shared/util.h"
#include "btio/btio.h"

#include "bnep.h"

#define CON_SETUP_RETRIES      3
#define CON_SETUP_TO           9

static int ctl;

static struct {
	const char	*name;		/* Friendly name */
	const char	*uuid128;	/* UUID 128 */
	uint16_t	id;		/* Service class identifier */
} __svc[] = {
	{ "panu",	PANU_UUID,	BNEP_SVC_PANU	},
	{ "gn",		GN_UUID,	BNEP_SVC_GN	},
	{ "nap",	NAP_UUID,	BNEP_SVC_NAP	},
	{ NULL }
};

struct __service_16 {
	uint16_t dst;
	uint16_t src;
} __attribute__ ((packed));

struct bnep {
	GIOChannel	*io;
	uint16_t	src;
	uint16_t	dst;
	bdaddr_t	dst_addr;
	char	iface[16];
	guint	attempts;
	guint	setup_to;
	guint	watch;
	bnep_connect_cb	conn_cb;
	void	*conn_data;
	bnep_disconnect_cb disconn_cb;
	void	*disconn_data;
};

const char *bnep_uuid(uint16_t id)
{
	int i;

	for (i = 0; __svc[i].uuid128; i++)
		if (__svc[i].id == id)
			return __svc[i].uuid128;
	return NULL;
}

const char *bnep_name(uint16_t id)
{
	int i;

	for (i = 0; __svc[i].name; i++)
		if (__svc[i].id == id)
			return __svc[i].name;
	return NULL;
}

int bnep_init(void)
{
	ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP);
	if (ctl < 0) {
		int err = -errno;

		if (err == -EPROTONOSUPPORT)
			warn("kernel lacks bnep-protocol support");
		else
			error("bnep: Failed to open control socket: %s (%d)",
							strerror(-err), -err);

		return err;
	}

	return 0;
}

int bnep_cleanup(void)
{
	close(ctl);
	return 0;
}

static int bnep_conndel(const bdaddr_t *dst)
{
	struct bnep_conndel_req req;

	memset(&req, 0, sizeof(req));
	baswap((bdaddr_t *)&req.dst, dst);
	req.flags = 0;
	if (ioctl(ctl, BNEPCONNDEL, &req) < 0) {
		int err = -errno;
		error("bnep: Failed to kill connection: %s (%d)",
							strerror(-err), -err);
		return err;
	}
	return 0;
}

static int bnep_connadd(int sk, uint16_t role, char *dev)
{
	struct bnep_connadd_req req;

	memset(&req, 0, sizeof(req));
	strncpy(req.device, dev, 16);
	req.device[15] = '\0';

	req.sock = sk;
	req.role = role;
	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
		int err = -errno;
		error("bnep: Failed to add device %s: %s(%d)",
						dev, strerror(-err), -err);
		return err;
	}

	strncpy(dev, req.device, 16);
	return 0;
}

static int bnep_if_up(const char *devname)
{
	struct ifreq ifr;
	int sk, err = 0;

	sk = socket(AF_INET, SOCK_DGRAM, 0);

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);

	ifr.ifr_flags |= IFF_UP;
	ifr.ifr_flags |= IFF_MULTICAST;

	if (ioctl(sk, SIOCSIFFLAGS, (void *) &ifr) < 0) {
		err = -errno;
		error("bnep: Could not bring up %s: %s(%d)",
						devname, strerror(-err), -err);
	}

	close(sk);

	return err;
}

static int bnep_if_down(const char *devname)
{
	struct ifreq ifr;
	int sk, err = 0;

	sk = socket(AF_INET, SOCK_DGRAM, 0);

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);

	ifr.ifr_flags &= ~IFF_UP;

	/* Bring down the interface */
	if (ioctl(sk, SIOCSIFFLAGS, (void *) &ifr) < 0) {
		err = -errno;
		error("bnep: Could not bring down %s: %s(%d)",
						devname, strerror(-err), -err);
	}

	close(sk);

	return err;
}

static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
								gpointer data)
{
	struct bnep *session = data;

	if (session->disconn_cb)
		session->disconn_cb(session->disconn_data);

	return FALSE;
}

static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
								gpointer data)
{
	struct bnep *session = data;
	struct bnep_control_rsp *rsp;
	struct timeval timeo;
	char pkt[BNEP_MTU];
	ssize_t r;
	int sk;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (session->setup_to > 0) {
		g_source_remove(session->setup_to);
		session->setup_to = 0;
	}

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		error("bnep: Hangup or error on l2cap server socket");
		goto failed;
	}

	sk = g_io_channel_unix_get_fd(chan);
	memset(pkt, 0, BNEP_MTU);
	r = read(sk, pkt, sizeof(pkt) - 1);
	if (r < 0) {
		error("bnep: IO Channel read error");
		goto failed;
	}

	if (r == 0) {
		error("bnep: No packet received on l2cap socket");
		goto failed;
	}

	errno = EPROTO;

	if ((size_t) r < sizeof(*rsp)) {
		error("bnep: Packet received is not bnep type");
		goto failed;
	}

	rsp = (void *) pkt;
	if (rsp->type != BNEP_CONTROL) {
		error("bnep: Packet received is not bnep type");
		goto failed;
	}

	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
		return TRUE;

	r = ntohs(rsp->resp);
	if (r != BNEP_SUCCESS) {
		error("bnep: failed");
		goto failed;
	}

	memset(&timeo, 0, sizeof(timeo));
	timeo.tv_sec = 0;
	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));

	sk = g_io_channel_unix_get_fd(session->io);
	if (bnep_connadd(sk, session->src, session->iface) < 0)
		goto failed;

	if (bnep_if_up(session->iface) < 0) {
		bnep_conndel(&session->dst_addr);
		goto failed;
	}

	session->watch = g_io_add_watch(session->io,
					G_IO_ERR | G_IO_HUP | G_IO_NVAL,
					(GIOFunc) bnep_watchdog_cb, session);
	g_io_channel_unref(session->io);
	session->io = NULL;

	session->conn_cb(session->iface, 0, session->conn_data);

	return FALSE;

failed:
	session->conn_cb(NULL, -EIO, session->conn_data);

	return FALSE;
}

static int bnep_setup_conn_req(struct bnep *session)
{
	struct bnep_setup_conn_req *req;
	struct __service_16 *s;
	unsigned char pkt[BNEP_MTU];
	int fd;

	/* Send request */
	req = (void *) pkt;
	req->type = BNEP_CONTROL;
	req->ctrl = BNEP_SETUP_CONN_REQ;
	req->uuid_size = 2;     /* 16bit UUID */
	s = (void *) req->service;
	s->src = htons(session->src);
	s->dst = htons(session->dst);

	fd = g_io_channel_unix_get_fd(session->io);
	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
		error("bnep: connection req send failed: %s", strerror(errno));
		return -errno;
	}

	session->attempts++;

	return 0;
}

static gboolean bnep_conn_req_to(gpointer user_data)
{
	struct bnep *session = user_data;

	if (session->attempts == CON_SETUP_RETRIES) {
		error("bnep: Too many bnep connection attempts");
	} else {
		error("bnep: connection setup TO, retrying...");
		if (bnep_setup_conn_req(session) == 0)
			return TRUE;
	}

	session->conn_cb(NULL, -ETIMEDOUT, session->conn_data);

	return FALSE;
}

struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
								char *iface)
{
	struct bnep *session;
	int dup_fd;

	dup_fd = dup(sk);
	if (dup_fd < 0)
		return NULL;

	session = g_new0(struct bnep, 1);
	session->io = g_io_channel_unix_new(dup_fd);
	session->src = local_role;
	session->dst = remote_role;
	strncpy(session->iface, iface, 16);
	session->iface[15] = '\0';

	g_io_channel_set_close_on_unref(session->io, TRUE);
	session->watch = g_io_add_watch(session->io,
				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
					(GIOFunc) bnep_setup_cb, session);

	return session;
}

void bnep_free(struct bnep *session)
{
	if (!session)
		return;

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

	if (session->watch > 0) {
		g_source_remove(session->watch);
		session->watch = 0;
	}

	g_free(session);
}

int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data)
{
	GError *gerr = NULL;
	int err;

	if (!session || !conn_cb)
		return -EINVAL;

	session->attempts = 0;
	session->conn_cb = conn_cb;
	session->conn_data = data;

	bt_io_get(session->io, &gerr, BT_IO_OPT_DEST_BDADDR, &session->dst_addr,
							BT_IO_OPT_INVALID);
	if (gerr) {
		error("bnep: connect failed: %s", gerr->message);
		g_error_free(gerr);
		return -EINVAL;
	}

	err = bnep_setup_conn_req(session);
	if (err < 0)
		return err;

	session->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
						bnep_conn_req_to, session);
	return 0;
}

void bnep_disconnect(struct bnep *session)
{
	if (!session)
		return;

	if (session->watch > 0) {
		g_source_remove(session->watch);
		session->watch = 0;
	}

	if (session->io) {
		g_io_channel_unref(session->io);
		session->io = NULL;
	}

	bnep_if_down(session->iface);
	bnep_conndel(&session->dst_addr);
}

void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
								void *data)
{
	if (!session || !disconn_cb)
		return;

	if (!session->disconn_cb && !session->disconn_data) {
		session->disconn_cb = disconn_cb;
		session->disconn_data = data;
	}
}

static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
	int ifindex;
	struct ifreq ifr;
	int sk, err = 0;

	if (!devname || !bridge)
		return -EINVAL;

	ifindex = if_nametoindex(devname);

	sk = socket(AF_INET, SOCK_STREAM, 0);
	if (sk < 0)
		return -1;

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
	ifr.ifr_ifindex = ifindex;

	if (ioctl(sk, SIOCBRADDIF, &ifr) < 0) {
		err = -errno;
		error("bnep: Can't add %s to the bridge %s: %s(%d)",
					devname, bridge, strerror(-err), -err);
	} else {
		info("bnep: bridge %s: interface %s added", bridge, devname);
	}

	close(sk);

	return err;
}

static int bnep_del_from_bridge(const char *devname, const char *bridge)
{
	int ifindex;
	struct ifreq ifr;
	int sk, err = 0;

	if (!devname || !bridge)
		return -EINVAL;

	ifindex = if_nametoindex(devname);

	sk = socket(AF_INET, SOCK_STREAM, 0);
	if (sk < 0)
		return -1;

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
	ifr.ifr_ifindex = ifindex;

	if (ioctl(sk, SIOCBRDELIF, &ifr) < 0) {
		err = -errno;
		error("bnep: Can't delete %s from the bridge %s: %s(%d)",
					devname, bridge, strerror(-err), -err);
	} else {
		info("bnep: bridge %s: interface %s removed", bridge, devname);
	}

	close(sk);

	return err;
}

int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
						const bdaddr_t *addr)
{
	int err;

	if (!bridge || !iface || !addr)
		return -EINVAL;

	err = bnep_connadd(sk, dst, iface);
	if (err < 0)
		return err;

	err = bnep_add_to_bridge(iface, bridge);
	if (err < 0) {
		bnep_conndel(addr);
		return err;
	}

	return bnep_if_up(iface);
}

void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
{
	if (!bridge || !iface || !addr)
		return;

	bnep_del_from_bridge(iface, bridge);
	bnep_if_down(iface);
	bnep_conndel(addr);
}

ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
{
	struct bnep_control_rsp rsp;

	rsp.type = type;
	rsp.ctrl = ctrl;
	rsp.resp = htons(resp);

	return send(sk, &rsp, sizeof(rsp), 0);
}

uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
								uint16_t *src)
{
	const uint8_t bt_base[] = { 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
					0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
	uint8_t *dest, *source;
	uint32_t val;

	dest = req->service;
	source = req->service + req->uuid_size;

	switch (req->uuid_size) {
	case 2: /* UUID16 */
		*dst = get_be16(dest);
		*src = get_be16(source);
		break;
	case 16: /* UUID128 */
		/* Check that the bytes in the UUID, except the service ID
		 * itself, are correct. The service ID is checked in
		 * bnep_setup_chk(). */
		if (memcmp(&dest[4], bt_base, sizeof(bt_base)) != 0)
			return BNEP_CONN_INVALID_DST;
		if (memcmp(&source[4], bt_base, sizeof(bt_base)) != 0)
			return BNEP_CONN_INVALID_SRC;

		/* Intentional no-break */

	case 4: /* UUID32 */
		val = get_be32(dest);
		if (val > 0xffff)
			return BNEP_CONN_INVALID_DST;

		*dst = val;

		val = get_be32(source);
		if (val > 0xffff)
			return BNEP_CONN_INVALID_SRC;

		*src = val;
		break;
	default:
		return BNEP_CONN_INVALID_SVC;
	}

	/* Allowed PAN Profile scenarios */
	switch (*dst) {
	case BNEP_SVC_NAP:
	case BNEP_SVC_GN:
		if (*src == BNEP_SVC_PANU)
			return BNEP_SUCCESS;
		return BNEP_CONN_INVALID_SRC;
	case BNEP_SVC_PANU:
		if (*src == BNEP_SVC_PANU || *src == BNEP_SVC_GN ||
							*src == BNEP_SVC_NAP)
			return BNEP_SUCCESS;

		return BNEP_CONN_INVALID_SRC;
	}

	return BNEP_CONN_INVALID_DST;
}
