/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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 <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <glib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <linux/if_bridge.h>

#include "btio/btio.h"
#include "lib/bluetooth.h"
#include "lib/bnep.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/uuid-helper.h"
#include "profiles/network/bnep.h"
#include "src/log.h"

#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "utils.h"
#include "bluetooth.h"
#include "pan.h"

#define SVC_HINT_NETWORKING 0x02

#define BNEP_BRIDGE "bt-pan"
#define BNEP_PANU_INTERFACE "bt-pan"
#define BNEP_NAP_INTERFACE "bt-pan%d"

struct pan_device {
	char		iface[16];
	bdaddr_t	dst;
	uint8_t		conn_state;
	uint8_t		role;
	GIOChannel	*io;
	struct bnep	*session;
	guint		watch;
};

static bdaddr_t adapter_addr;
static GSList *devices = NULL;
static uint8_t local_role = HAL_PAN_ROLE_NONE;
static uint32_t nap_rec_id = 0;
static uint32_t panu_rec_id = 0;
static GIOChannel *nap_io = NULL;
static bool nap_bridge_mode = false;
static struct ipc *hal_ipc = NULL;

static int set_forward_delay(int sk)
{
	unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0 , 0, 0 };
	struct ifreq ifr;

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, BNEP_BRIDGE, IFNAMSIZ);
	ifr.ifr_data = (char *) args;

	if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) {
		error("pan: setting forward delay failed: %d (%s)",
							errno, strerror(errno));
		return -1;
	}

	return 0;
}

static int nap_create_bridge(void)
{
	int sk, err;

	DBG("%s", BNEP_BRIDGE);

	if (nap_bridge_mode)
		return 0;

	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
	if (sk < 0)
		return -EOPNOTSUPP;

	if (ioctl(sk, SIOCBRADDBR, BNEP_BRIDGE) < 0) {
		err = -errno;
		if (err != -EEXIST) {
			close(sk);
			return -EOPNOTSUPP;
		}
	}

	err = set_forward_delay(sk);
	if (err < 0)
		ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);

	close(sk);

	nap_bridge_mode = err == 0;

	return err;
}

static int bridge_if_down(void)
{
	struct ifreq ifr;
	int sk, err;

	sk = socket(AF_INET, SOCK_DGRAM, 0);

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

	ifr.ifr_flags &= ~IFF_UP;

	/* Bring down the interface */
	err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);

	close(sk);

	if (err < 0) {
		error("pan: Could not bring down %s", BNEP_BRIDGE);
		return err;
	}

	return 0;
}

static int nap_remove_bridge(void)
{
	int sk, err;

	DBG("%s", BNEP_BRIDGE);

	if (!nap_bridge_mode)
		return 0;

	bridge_if_down();

	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
	if (sk < 0)
		return -EOPNOTSUPP;

	err = ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
	if (err < 0)
		err = -errno;

	close(sk);

	if (err < 0)
		return err;

	nap_bridge_mode = false;

	return 0;
}

static int device_cmp(gconstpointer s, gconstpointer user_data)
{
	const struct pan_device *dev = s;
	const bdaddr_t *dst = user_data;

	return bacmp(&dev->dst, dst);
}

static void pan_device_free(void *data)
{
	struct pan_device *dev = data;

	if (dev->watch > 0) {
		bnep_server_delete(BNEP_BRIDGE, dev->iface, &dev->dst);
		g_source_remove(dev->watch);
	}

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

	if (dev->session)
		bnep_free(dev->session);

	g_free(dev);
}

static void pan_device_remove(struct pan_device *dev)
{
	devices = g_slist_remove(devices, dev);

	if (g_slist_length(devices) == 0) {
		local_role = HAL_PAN_ROLE_NONE;
		nap_remove_bridge();
	}

	pan_device_free(dev);
}

static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
{
	struct hal_ev_pan_conn_state ev;
	char addr[18];

	if (dev->conn_state == state)
		return;

	dev->conn_state = state;
	ba2str(&dev->dst, addr);
	DBG("device %s state %u", addr, state);

	bdaddr2android(&dev->dst, ev.bdaddr);
	ev.state = state;
	ev.local_role = local_role;
	ev.remote_role = dev->role;
	ev.status = HAL_STATUS_SUCCESS;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE,
							sizeof(ev), &ev);
	if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
		pan_device_remove(dev);
}

static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state,
								uint8_t status)
{
	struct hal_ev_pan_ctrl_state ev;

	DBG("");

	ev.state = state;
	ev.local_role = local_role;
	ev.status = status;

	memset(ev.name, 0, sizeof(ev.name));

	if (local_role == HAL_PAN_ROLE_NAP)
		memcpy(ev.name, BNEP_BRIDGE, sizeof(BNEP_BRIDGE));
	else if (local_role == HAL_PAN_ROLE_PANU)
		memcpy(ev.name, dev->iface, sizeof(dev->iface));

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE,
							sizeof(ev), &ev);
}

static void bnep_disconn_cb(void *data)
{
	struct pan_device *dev = data;

	DBG("%s disconnected", dev->iface);

	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
}

static void bnep_conn_cb(char *iface, int err, void *data)
{
	struct pan_device *dev = data;

	DBG("");

	if (err < 0) {
		error("bnep connect req failed: %s", strerror(-err));
		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
		return;
	}

	memcpy(dev->iface, iface, sizeof(dev->iface));

	DBG("%s connected", dev->iface);

	bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED, HAL_STATUS_SUCCESS);
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
}

static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
	struct pan_device *dev = data;
	uint16_t l_role, r_role;
	int perr, sk;

	DBG("");

	if (err) {
		error("%s", err->message);
		goto fail;
	}

	l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
								BNEP_SVC_PANU;
	r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;

	sk = g_io_channel_unix_get_fd(dev->io);

	dev->session = bnep_new(sk, l_role, r_role, BNEP_PANU_INTERFACE);
	if (!dev->session)
		goto fail;

	perr = bnep_connect(dev->session, bnep_conn_cb, dev);
	if (perr < 0) {
		error("bnep connect req failed: %s", strerror(-perr));
		goto fail;
	}

	bnep_set_disconnect(dev->session, bnep_disconn_cb, dev);

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

	return;

fail:
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
}

static void bt_pan_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_pan_connect *cmd = buf;
	struct pan_device *dev;
	uint8_t status;
	bdaddr_t dst;
	char addr[18];
	GSList *l;
	GError *gerr = NULL;

	DBG("");

	switch (cmd->local_role) {
	case HAL_PAN_ROLE_NAP:
		if (cmd->remote_role != HAL_PAN_ROLE_PANU) {
			status = HAL_STATUS_UNSUPPORTED;
			goto failed;
		}
		break;
	case HAL_PAN_ROLE_PANU:
		if (cmd->remote_role != HAL_PAN_ROLE_NAP &&
					cmd->remote_role != HAL_PAN_ROLE_PANU) {
			status = HAL_STATUS_UNSUPPORTED;
			goto failed;
		}
		break;
	default:
		status = HAL_STATUS_UNSUPPORTED;
		goto failed;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = g_new0(struct pan_device, 1);
	bacpy(&dev->dst, &dst);
	local_role = cmd->local_role;
	dev->role = cmd->remote_role;

	ba2str(&dev->dst, addr);
	DBG("connecting to %s %s", addr, dev->iface);

	dev->io = bt_io_connect(connect_cb, dev, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, BNEP_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_OMTU, BNEP_MTU,
					BT_IO_OPT_IMTU, BNEP_MTU,
					BT_IO_OPT_INVALID);
	if (!dev->io) {
		error("%s", gerr->message);
		g_error_free(gerr);
		g_free(dev);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	devices = g_slist_append(devices, dev);
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
}

static void bt_pan_disconnect(const void *buf, uint16_t len)
{
	const struct hal_cmd_pan_disconnect *cmd = buf;
	struct pan_device *dev;
	uint8_t status;
	GSList *l;
	bdaddr_t dst;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	if (dev->conn_state == HAL_PAN_STATE_CONNECTED && dev->session)
		bnep_disconnect(dev->session);

	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT,
									status);
}

static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond,
							gpointer user_data)
{
	struct pan_device *dev = user_data;

	DBG("disconnected");

	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);

	return FALSE;
}

static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
							gpointer user_data)
{
	struct pan_device *dev = user_data;
	uint8_t packet[BNEP_MTU];
	struct bnep_setup_conn_req *req = (void *) packet;
	uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
	int sk, n, err;

	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
		error("Hangup or error or inval on BNEP socket");
		return FALSE;
	}

	sk = g_io_channel_unix_get_fd(chan);

	/* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
	n = read(sk, packet, sizeof(packet));
	if (n  < 0) {
		error("read(): %s(%d)", strerror(errno), errno);
		goto failed;
	}

	/* Highest known control command id BNEP_FILTER_MULT_ADDR_RSP 0x06 */
	if (req->type == BNEP_CONTROL &&
					req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
		error("cmd not understood");
		bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_CMD_NOT_UNDERSTOOD,
								req->ctrl);
		goto failed;
	}

	if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) {
		error("cmd is not BNEP_SETUP_CONN_REQ %02X %02X", req->type,
								req->ctrl);
		goto failed;
	}

	rsp = bnep_setup_decode(req, &dst_role, &src_role);
	if (rsp != BNEP_SUCCESS) {
		error("bnep_setup_decode failed");
		goto failed;
	}

	err = nap_create_bridge();
	if (err < 0) {
		error("pan: Failed to create bridge: %s (%d)", strerror(-err),
									-err);
		goto failed;
	}

	if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
							&dev->dst) < 0) {
		error("pan: server_connadd failed");
		rsp = BNEP_CONN_NOT_ALLOWED;
		goto failed;
	}

	rsp = BNEP_SUCCESS;
	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);

	dev->watch = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
							nap_watchdog_cb, dev);
	g_io_channel_unref(dev->io);
	dev->io = NULL;

	bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED, HAL_STATUS_SUCCESS);
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);

	return FALSE;

failed:
	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
	pan_device_remove(dev);

	return FALSE;
}

static void nap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct pan_device *dev = user_data;

	DBG("");

	if (err) {
		error("%s", err->message);
		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
		return;
	}

	g_io_channel_set_close_on_unref(chan, TRUE);
	dev->watch = g_io_add_watch(chan,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				nap_setup_cb, dev);
}

static void nap_confirm_cb(GIOChannel *chan, gpointer data)
{
	struct pan_device *dev;
	bdaddr_t dst;
	char address[18];
	GError *err = NULL;

	DBG("");

	bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		return;
	}

	DBG("incoming connect request from %s", address);
	dev = g_new0(struct pan_device, 1);
	bacpy(&dev->dst, &dst);
	local_role = HAL_PAN_ROLE_NAP;
	dev->role = HAL_PAN_ROLE_PANU;

	strncpy(dev->iface, BNEP_NAP_INTERFACE, 16);
	dev->iface[15] = '\0';

	dev->io = g_io_channel_ref(chan);
	g_io_channel_set_close_on_unref(dev->io, TRUE);

	if (!bt_io_accept(dev->io, nap_connect_cb, dev, NULL, &err)) {
		error("bt_io_accept: %s", err->message);
		g_error_free(err);
		goto failed;
	}

	devices = g_slist_append(devices, dev);
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);

	return;

failed:
	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
}

static void destroy_nap_device(void)
{
	DBG("");

	nap_remove_bridge();

	if (nap_io) {
		g_io_channel_shutdown(nap_io, FALSE, NULL);
		g_io_channel_unref(nap_io);
		nap_io = NULL;
	}
}

static int register_nap_server(void)
{
	GError *gerr = NULL;

	DBG("");

	nap_io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_PSM, BNEP_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_OMTU, BNEP_MTU,
					BT_IO_OPT_IMTU, BNEP_MTU,
					BT_IO_OPT_INVALID);

	if (!nap_io) {
		destroy_nap_device();
		error("%s", gerr->message);
		g_error_free(gerr);
		return -EIO;
	}

	return 0;
}

static void bt_pan_enable(const void *buf, uint16_t len)
{
	const struct hal_cmd_pan_enable *cmd = buf;
	uint8_t status, state;
	int err;

	DBG("");

	if (local_role == cmd->local_role) {
		status = HAL_STATUS_SUCCESS;
		goto reply;
	}

	/* destroy existing server */
	destroy_nap_device();

	switch (cmd->local_role) {
	case HAL_PAN_ROLE_NAP:
		break;
	case HAL_PAN_ROLE_NONE:
		local_role = HAL_PAN_ROLE_NONE;
		status = HAL_STATUS_SUCCESS;
		state = HAL_PAN_CTRL_DISABLED;
		goto notify;
	default:
		status = HAL_STATUS_UNSUPPORTED;
		goto reply;
	}

	local_role = cmd->local_role;
	err = register_nap_server();
	if (err < 0) {
		status = HAL_STATUS_FAILED;
		destroy_nap_device();
		goto reply;
	}

	status = HAL_STATUS_SUCCESS;
	state = HAL_PAN_CTRL_ENABLED;

notify:
	bt_pan_notify_ctrl_state(NULL, state, status);

reply:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
}

static void bt_pan_get_role(const void *buf, uint16_t len)
{
	struct hal_rsp_pan_get_role rsp;

	DBG("");

	rsp.local_role = local_role;
	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE,
							sizeof(rsp), &rsp, -1);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_PAN_ENABLE */
	{ bt_pan_enable, false, sizeof(struct hal_cmd_pan_enable) },
	/* HAL_OP_PAN_GET_ROLE */
	{ bt_pan_get_role, false, 0 },
	/* HAL_OP_PAN_CONNECT */
	{ bt_pan_connect, false, sizeof(struct hal_cmd_pan_connect) },
	/* HAL_OP_PAN_DISCONNECT */
	{ bt_pan_disconnect, false, sizeof(struct hal_cmd_pan_disconnect) },
};

static sdp_record_t *nap_record(void)
{
	sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
	uuid_t root_uuid, nap, l2cap, bnep;
	sdp_profile_desc_t profile[1];
	sdp_list_t *proto[2];
	sdp_data_t *v, *p;
	uint16_t psm = BNEP_PSM, version = 0x0100;
	uint16_t security = 0x0001, type = 0xfffe;
	uint32_t rate = 0;
	const char *desc = "Network Access Point", *name = "Network Service";
	sdp_record_t *record;
	uint16_t ptype[] = { 0x0800, /* IPv4 */ 0x0806,  /* ARP */ };
	sdp_data_t *head, *pseq, *data;

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	record->attrlist = NULL;
	record->pattern = NULL;

	sdp_uuid16_create(&nap, NAP_SVCLASS_ID);
	svclass = sdp_list_append(NULL, &nap);
	sdp_set_service_classes(record, svclass);

	sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
	profile[0].version = 0x0100;
	pfseq = sdp_list_append(NULL, &profile[0]);
	sdp_set_profile_descs(record, pfseq);
	sdp_set_info_attr(record, name, NULL, desc);
	sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &type);
	sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE,
							SDP_UINT32, &rate);

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(NULL, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&l2cap, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap);
	p = sdp_data_alloc(SDP_UINT16, &psm);
	proto[0] = sdp_list_append(proto[0], p);
	apseq = sdp_list_append(NULL, proto[0]);

	sdp_uuid16_create(&bnep, BNEP_UUID);
	proto[1] = sdp_list_append(NULL, &bnep);
	v = sdp_data_alloc(SDP_UINT16, &version);
	proto[1] = sdp_list_append(proto[1], v);

	head = sdp_data_alloc(SDP_UINT16, &ptype[0]);
	data = sdp_data_alloc(SDP_UINT16, &ptype[1]);
	sdp_seq_append(head, data);

	pseq = sdp_data_alloc(SDP_SEQ16, head);
	proto[1] = sdp_list_append(proto[1], pseq);
	apseq = sdp_list_append(apseq, proto[1]);
	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);
	sdp_add_lang_attr(record);
	sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security);

	sdp_data_free(p);
	sdp_data_free(v);
	sdp_list_free(apseq, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(svclass, NULL);
	sdp_list_free(pfseq, NULL);

	return record;
}

static sdp_record_t *panu_record(void)
{
	sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
	uuid_t root_uuid, panu, l2cap, bnep;
	sdp_profile_desc_t profile[1];
	sdp_list_t *proto[2];
	sdp_data_t *v, *p;
	uint16_t psm = BNEP_PSM, version = 0x0100;
	uint16_t security = 0x0001, type = 0xfffe;
	uint32_t rate = 0;
	const char *desc = "PAN User", *name = "Network Service";
	sdp_record_t *record;
	uint16_t ptype[] = { 0x0800, /* IPv4 */ 0x0806,  /* ARP */ };
	sdp_data_t *head, *pseq, *data;

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	record->attrlist = NULL;
	record->pattern = NULL;

	sdp_uuid16_create(&panu, PANU_SVCLASS_ID);
	svclass = sdp_list_append(NULL, &panu);
	sdp_set_service_classes(record, svclass);

	sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
	profile[0].version = 0x0100;
	pfseq = sdp_list_append(NULL, &profile[0]);
	sdp_set_profile_descs(record, pfseq);
	sdp_set_info_attr(record, name, NULL, desc);
	sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &type);
	sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE,
							SDP_UINT32, &rate);

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(NULL, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&l2cap, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap);
	p = sdp_data_alloc(SDP_UINT16, &psm);
	proto[0] = sdp_list_append(proto[0], p);
	apseq = sdp_list_append(NULL, proto[0]);

	sdp_uuid16_create(&bnep, BNEP_UUID);
	proto[1] = sdp_list_append(NULL, &bnep);
	v = sdp_data_alloc(SDP_UINT16, &version);
	proto[1] = sdp_list_append(proto[1], v);

	head = sdp_data_alloc(SDP_UINT16, &ptype[0]);
	data = sdp_data_alloc(SDP_UINT16, &ptype[1]);
	sdp_seq_append(head, data);

	pseq = sdp_data_alloc(SDP_SEQ16, head);
	proto[1] = sdp_list_append(proto[1], pseq);
	apseq = sdp_list_append(apseq, proto[1]);
	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);
	sdp_add_lang_attr(record);
	sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security);

	sdp_data_free(p);
	sdp_data_free(v);
	sdp_list_free(apseq, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(svclass, NULL);
	sdp_list_free(pfseq, NULL);

	return record;
}

bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	sdp_record_t *nap_rec, *panu_rec;
	int err;

	DBG("");

	bacpy(&adapter_addr, addr);

	nap_rec = nap_record();
	if (bt_adapter_add_record(nap_rec, SVC_HINT_NETWORKING) < 0) {
		sdp_record_free(nap_rec);
		error("Failed to allocate PAN-NAP sdp record");
		return false;
	}

	panu_rec = panu_record();
	if (bt_adapter_add_record(panu_rec, SVC_HINT_NETWORKING) < 0) {
		sdp_record_free(nap_rec);
		sdp_record_free(panu_rec);
		error("Failed to allocate PAN-PANU sdp record");
		return false;
	}

	err = bnep_init();
	if (err < 0) {
		error("Failed to init BNEP");
		bt_adapter_remove_record(nap_rec->handle);
		bt_adapter_remove_record(panu_rec->handle);
		return false;
	}

	err = register_nap_server();
	if (err < 0) {
		error("Failed to register NAP server");
		bt_adapter_remove_record(nap_rec->handle);
		bt_adapter_remove_record(panu_rec->handle);
		bnep_cleanup();
		return false;
	}

	nap_rec_id = nap_rec->handle;
	panu_rec_id = panu_rec->handle;

	hal_ipc = ipc;
	ipc_register(hal_ipc, HAL_SERVICE_ID_PAN, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
}

void bt_pan_unregister(void)
{
	DBG("");

	g_slist_free_full(devices, pan_device_free);
	devices = NULL;
	local_role = HAL_PAN_ROLE_NONE;

	bnep_cleanup();

	ipc_unregister(hal_ipc, HAL_SERVICE_ID_PAN);
	hal_ipc = NULL;

	bt_adapter_remove_record(nap_rec_id);
	nap_rec_id = 0;
	bt_adapter_remove_record(panu_rec_id);
	panu_rec_id = 0;
	destroy_nap_device();
}
