/*
 *
 *  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 <glib.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>

#include "lib/bluetooth.h"
#include "btio/btio.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/sdp-client.h"
#include "src/sdpd.h"
#include "src/log.h"

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

#define RFCOMM_CHANNEL_MAX 30

#define OPP_DEFAULT_CHANNEL	9
#define HSP_AG_DEFAULT_CHANNEL	12
#define HFP_AG_DEFAULT_CHANNEL	13
#define PBAP_DEFAULT_CHANNEL	15
#define MAP_MAS_DEFAULT_CHANNEL	16

#define SVC_HINT_OBEX 0x10

/* Hardcoded MAP stuff needed for MAS SMS Instance.*/
#define DEFAULT_MAS_INSTANCE	0x00

#define MAP_MSG_TYPE_SMS_GSM	0x02
#define MAP_MSG_TYPE_SMS_CDMA	0x04
#define DEFAULT_MAS_MSG_TYPE	(MAP_MSG_TYPE_SMS_GSM | MAP_MSG_TYPE_SMS_CDMA)

static struct ipc *hal_ipc = NULL;
struct rfcomm_sock {
	int channel;	/* RFCOMM channel */
	BtIOSecLevel sec_level;

	/* for socket to BT */
	int bt_sock;
	guint bt_watch;

	/* for socket to HAL */
	int jv_sock;
	guint jv_watch;

	bdaddr_t dst;
	uint32_t service_handle;

	uint8_t *buf;
	int buf_size;
};

struct rfcomm_channel {
	bool reserved;
	struct rfcomm_sock *rfsock;
};

static bdaddr_t adapter_addr;

static const uint8_t zero_uuid[16] = { 0 };

/* Simple list of RFCOMM connected sockets */
static GList *connections = NULL;

static struct rfcomm_channel servers[RFCOMM_CHANNEL_MAX + 1];

static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
{
	socklen_t len = sizeof(int);
	int rcv, snd, size, err;

	err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_RCVBUF, &rcv, &len);
	if (err < 0) {
		int err = -errno;
		error("getsockopt(SO_RCVBUF): %s", strerror(-err));
		return err;
	}

	err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_SNDBUF, &snd, &len);
	if (err < 0) {
		int err = -errno;
		error("getsockopt(SO_SNDBUF): %s", strerror(-err));
		return err;
	}

	size = MAX(rcv, snd);

	DBG("Set buffer size %d", size);

	rfsock->buf = g_malloc(size);
	rfsock->buf_size = size;

	return 0;
}

static void cleanup_rfsock(gpointer data)
{
	struct rfcomm_sock *rfsock = data;

	DBG("rfsock %p bt_sock %d jv_sock %d", rfsock, rfsock->bt_sock,
							rfsock->jv_sock);

	if (rfsock->jv_sock >= 0)
		if (close(rfsock->jv_sock) < 0)
			error("close() fd %d failed: %s", rfsock->jv_sock,
							strerror(errno));

	if (rfsock->bt_sock >= 0)
		if (close(rfsock->bt_sock) < 0)
			error("close() fd %d: failed: %s", rfsock->bt_sock,
							strerror(errno));

	if (rfsock->bt_watch > 0)
		if (!g_source_remove(rfsock->bt_watch))
			error("bt_watch source was not found");

	if (rfsock->jv_watch > 0)
		if (!g_source_remove(rfsock->jv_watch))
			error("stack_watch source was not found");

	if (rfsock->service_handle)
		bt_adapter_remove_record(rfsock->service_handle);

	if (rfsock->buf)
		g_free(rfsock->buf);

	g_free(rfsock);
}

static struct rfcomm_sock *create_rfsock(int bt_sock, int *hal_sock)
{
	int fds[2] = {-1, -1};
	struct rfcomm_sock *rfsock;

	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
		error("socketpair(): %s", strerror(errno));
		*hal_sock = -1;
		return NULL;
	}

	rfsock = g_new0(struct rfcomm_sock, 1);
	rfsock->jv_sock = fds[0];
	*hal_sock = fds[1];
	rfsock->bt_sock = bt_sock;

	DBG("rfsock %p", rfsock);

	if (bt_sock < 0)
		return rfsock;

	if (rfsock_set_buffer(rfsock) < 0) {
		cleanup_rfsock(rfsock);
		return NULL;
	}

	return rfsock;
}

static sdp_record_t *create_rfcomm_record(uint8_t chan, uuid_t *uuid,
						const char *svc_name,
						bool has_obex)
{
	sdp_list_t *svclass_id;
	sdp_list_t *seq, *proto_seq, *pbg_seq;
	sdp_list_t *proto[3];
	uuid_t l2cap_uuid, rfcomm_uuid, obex_uuid, pbg_uuid;
	sdp_data_t *channel;
	sdp_record_t *record;

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

	record->handle =  sdp_next_handle();

	svclass_id = sdp_list_append(NULL, uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
	seq = sdp_list_append(NULL, proto[0]);

	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
	proto[1] = sdp_list_append(NULL, &rfcomm_uuid);
	channel = sdp_data_alloc(SDP_UINT8, &chan);
	proto[1] = sdp_list_append(proto[1], channel);
	seq = sdp_list_append(seq, proto[1]);

	if (has_obex) {
		sdp_uuid16_create(&obex_uuid, OBEX_UUID);
		proto[2] = sdp_list_append(NULL, &obex_uuid);
		seq = sdp_list_append(seq, proto[2]);
	}

	proto_seq = sdp_list_append(NULL, seq);
	sdp_set_access_protos(record, proto_seq);

	sdp_uuid16_create(&pbg_uuid, PUBLIC_BROWSE_GROUP);
	pbg_seq = sdp_list_append(NULL, &pbg_uuid);
	sdp_set_browse_groups(record, pbg_seq);

	if (svc_name)
		sdp_set_info_attr(record, svc_name, NULL, NULL);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	if (has_obex)
		sdp_list_free(proto[2], NULL);
	sdp_list_free(seq, NULL);
	sdp_list_free(proto_seq, NULL);
	sdp_list_free(pbg_seq, NULL);
	sdp_list_free(svclass_id, NULL);

	return record;
}

static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
{
	uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
	uint8_t dtd = SDP_UINT8;
	uuid_t uuid;
	sdp_list_t *seq;
	sdp_profile_desc_t profile[1];
	void *dtds[sizeof(formats)], *values[sizeof(formats)];
	sdp_data_t *formats_list;
	sdp_record_t *record;
	size_t i;

	sdp_uuid16_create(&uuid, OBEX_OBJPUSH_SVCLASS_ID);

	record = create_rfcomm_record(chan, &uuid, svc_name, true);
	if (!record)
		return NULL;

	sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
	profile[0].version = 0x0100;
	seq = sdp_list_append(NULL, profile);
	sdp_set_profile_descs(record, seq);

	for (i = 0; i < sizeof(formats); i++) {
		dtds[i] = &dtd;
		values[i] = &formats[i];
	}
	formats_list = sdp_seq_alloc(dtds, values, sizeof(formats));
	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FORMATS_LIST, formats_list);

	sdp_list_free(seq, NULL);

	return record;
}

static sdp_record_t *create_pbap_record(uint8_t chan, const char *svc_name)
{
	sdp_list_t *seq;
	sdp_profile_desc_t profile[1];
	uint8_t formats = 0x01;
	sdp_record_t *record;
	uuid_t uuid;

	sdp_uuid16_create(&uuid, PBAP_PSE_SVCLASS_ID);

	record = create_rfcomm_record(chan, &uuid, svc_name, true);
	if (!record)
		return NULL;

	sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
	profile[0].version = 0x0101;
	seq = sdp_list_append(NULL, profile);
	sdp_set_profile_descs(record, seq);

	sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_REPOSITORIES, SDP_UINT8,
								&formats);

	sdp_list_free(seq, NULL);

	return record;
}

static sdp_record_t *create_mas_record(uint8_t chan, const char *svc_name)
{
	sdp_list_t *seq;
	sdp_profile_desc_t profile[1];
	uint8_t minst = DEFAULT_MAS_INSTANCE;
	uint8_t mtype = DEFAULT_MAS_MSG_TYPE;
	sdp_record_t *record;
	uuid_t uuid;

	sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID);

	record = create_rfcomm_record(chan, &uuid, svc_name, true);
	if (!record)
		return NULL;

	sdp_uuid16_create(&profile[0].uuid, MAP_PROFILE_ID);
	profile[0].version = 0x0101;
	seq = sdp_list_append(NULL, profile);
	sdp_set_profile_descs(record, seq);

	sdp_attr_add_new(record, SDP_ATTR_MAS_INSTANCE_ID, SDP_UINT8, &minst);
	sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_MESSAGE_TYPES, SDP_UINT8,
									&mtype);

	sdp_list_free(seq, NULL);

	return record;
}

static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name)
{
	sdp_record_t *record;
	uuid_t uuid;

	sdp_uuid16_create(&uuid, SERIAL_PORT_SVCLASS_ID);

	record = create_rfcomm_record(chan, &uuid, svc_name, false);
	if (!record)
		return NULL;

	return record;
}

static sdp_record_t *create_app_record(uint8_t chan,
						const uint8_t *app_uuid,
						const char *svc_name)
{
	sdp_record_t *record;
	uuid_t uuid;

	sdp_uuid128_create(&uuid, app_uuid);

	record = create_rfcomm_record(chan, &uuid, svc_name, false);
	if (!record)
		return NULL;

	return record;
}

static const struct profile_info {
	uint8_t		uuid[16];
	uint8_t		channel;
	uint8_t		svc_hint;
	BtIOSecLevel	sec_level;
	sdp_record_t *	(*create_record)(uint8_t chan, const char *svc_name);
} profiles[] = {
	{
		.uuid = {
			0x00, 0x00, 0x11, 0x08, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = HSP_AG_DEFAULT_CHANNEL,
		.svc_hint = 0,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = NULL
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = HFP_AG_DEFAULT_CHANNEL,
		.svc_hint = 0,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = NULL
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = PBAP_DEFAULT_CHANNEL,
		.svc_hint = SVC_HINT_OBEX,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = create_pbap_record
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		  },
		.channel = OPP_DEFAULT_CHANNEL,
		.svc_hint = SVC_HINT_OBEX,
		.sec_level = BT_IO_SEC_LOW,
		.create_record = create_opp_record
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = MAP_MAS_DEFAULT_CHANNEL,
		.svc_hint = SVC_HINT_OBEX,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = create_mas_record
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = 0,
		.svc_hint = 0,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = create_spp_record
	},
};

static uint32_t sdp_service_register(uint8_t channel, const uint8_t *uuid,
					const struct profile_info *profile,
					const void *svc_name)
{
	sdp_record_t *record = NULL;
	uint8_t svc_hint = 0;

	if (profile && profile->create_record) {
		record = profile->create_record(channel, svc_name);
		svc_hint = profile->svc_hint;
	} else if (uuid) {
		record = create_app_record(channel, uuid, svc_name);
	}

	if (!record)
		return 0;

	if (bt_adapter_add_record(record, svc_hint) < 0) {
		error("Failed to register on SDP record");
		sdp_record_free(record);
		return 0;
	}

	return record->handle;
}

static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
{
	ssize_t ret;
	struct msghdr msg;
	struct cmsghdr *cmsg;
	struct iovec iv;
	char cmsgbuf[CMSG_SPACE(sizeof(int))];

	DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);

	if (sock_fd == -1 || send_fd == -1)
		return -1;

	memset(&msg, 0, sizeof(msg));
	memset(cmsgbuf, 0, sizeof(cmsgbuf));

	msg.msg_control = cmsgbuf;
	msg.msg_controllen = sizeof(cmsgbuf);

	cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;
	cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));

	memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));

	iv.iov_base = (unsigned char *) buf;
	iv.iov_len = len;

	msg.msg_iov = &iv;
	msg.msg_iovlen = 1;

	ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
	if (ret < 0) {
		error("sendmsg(): sock_fd %d send_fd %d: %s",
					sock_fd, send_fd, strerror(errno));
		return ret;
	}

	return ret;
}

static const struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
{
	unsigned int i;

	for (i = 0; i < G_N_ELEMENTS(profiles); i++) {
		if (!memcmp(profiles[i].uuid, uuid, 16))
			return &profiles[i];
	}

	return NULL;
}

static int try_write_all(int fd, unsigned char *buf, int len)
{
	int sent = 0;

	while (len > 0) {
		int written;

		written = write(fd, buf, len);
		if (written < 0) {
			if (errno == EINTR || errno == EAGAIN)
				continue;
			return -1;
		}

		if (!written)
			return 0;

		len -= written; buf += written; sent += written;
	}

	return sent;
}

static gboolean jv_sock_client_event_cb(GIOChannel *io, GIOCondition cond,
								gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	int len, sent;

	if (cond & G_IO_HUP) {
		DBG("Socket %d hang up", g_io_channel_unix_get_fd(io));
		goto fail;
	}

	if (cond & (G_IO_ERR | G_IO_NVAL)) {
		error("Socket %d error", g_io_channel_unix_get_fd(io));
		goto fail;
	}

	len = read(rfsock->jv_sock, rfsock->buf, rfsock->buf_size);
	if (len <= 0) {
		error("read(): %s", strerror(errno));
		/* Read again */
		return TRUE;
	}

	sent = try_write_all(rfsock->bt_sock, rfsock->buf, len);
	if (sent < 0) {
		error("write(): %s", strerror(errno));
		goto fail;
	}

	return TRUE;
fail:
	DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond);

	connections = g_list_remove(connections, rfsock);
	cleanup_rfsock(rfsock);

	return FALSE;
}

static gboolean bt_sock_event_cb(GIOChannel *io, GIOCondition cond,
								gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	int len, sent;

	if (cond & G_IO_HUP) {
		DBG("Socket %d hang up", g_io_channel_unix_get_fd(io));
		goto fail;
	}

	if (cond & (G_IO_ERR | G_IO_NVAL)) {
		error("Socket %d error", g_io_channel_unix_get_fd(io));
		goto fail;
	}

	len = read(rfsock->bt_sock, rfsock->buf, rfsock->buf_size);
	if (len <= 0) {
		error("read(): %s", strerror(errno));
		/* Read again */
		return TRUE;
	}

	sent = try_write_all(rfsock->jv_sock, rfsock->buf, len);
	if (sent < 0) {
		error("write(): %s", strerror(errno));
		goto fail;
	}

	return TRUE;
fail:
	DBG("rfsock %p bt_sock %d cond %d", rfsock, rfsock->bt_sock, cond);

	connections = g_list_remove(connections, rfsock);
	cleanup_rfsock(rfsock);

	return FALSE;
}

static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
							int fd_accepted)
{
	struct hal_sock_connect_signal cmd;
	int len;

	DBG("");

	cmd.size = sizeof(cmd);
	bdaddr2android(bdaddr, cmd.bdaddr);
	cmd.channel = rfsock->channel;
	cmd.status = 0;

	len = bt_sock_send_fd(rfsock->jv_sock, &cmd, sizeof(cmd), fd_accepted);
	if (len != sizeof(cmd)) {
		error("Error sending accept signal");
		return false;
	}

	return true;
}

static gboolean jv_sock_server_event_cb(GIOChannel *io, GIOCondition cond,
								gpointer data)
{
	struct rfcomm_sock *rfsock = data;

	DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond);

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_ERR | G_IO_HUP)) {
		servers[rfsock->channel].rfsock = NULL;
		cleanup_rfsock(rfsock);
	}

	return FALSE;
}

static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
	struct rfcomm_sock *rfsock = user_data;
	struct rfcomm_sock *new_rfsock;
	GIOChannel *jv_io;
	GError *gerr = NULL;
	bdaddr_t dst;
	char address[18];
	int new_sock;
	int hal_sock;
	guint id;
	GIOCondition cond;

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

	bt_io_get(io, &gerr,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		g_io_channel_shutdown(io, TRUE, NULL);
		return;
	}

	ba2str(&dst, address);
	DBG("Incoming connection from %s on channel %d (rfsock %p)", address,
						rfsock->channel, rfsock);

	new_sock = g_io_channel_unix_get_fd(io);
	new_rfsock = create_rfsock(new_sock, &hal_sock);
	if (!new_rfsock) {
		g_io_channel_shutdown(io, TRUE, NULL);
		return;
	}

	DBG("new rfsock %p bt_sock %d jv_sock %d hal_sock %d", new_rfsock,
			new_rfsock->bt_sock, new_rfsock->jv_sock, hal_sock);

	if (!sock_send_accept(rfsock, &dst, hal_sock)) {
		cleanup_rfsock(new_rfsock);
		return;
	}

	connections = g_list_append(connections, new_rfsock);

	/* Handle events from Android */
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	jv_io = g_io_channel_unix_new(new_rfsock->jv_sock);
	id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, new_rfsock);
	g_io_channel_unref(jv_io);

	new_rfsock->jv_watch = id;

	/* Handle rfcomm events */
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	id = g_io_add_watch(io, cond, bt_sock_event_cb, new_rfsock);
	g_io_channel_set_close_on_unref(io, FALSE);

	new_rfsock->bt_watch = id;
}

static int find_free_channel(void)
{
	int ch;

	/* channel 0 is reserver so we don't use it */
	for (ch = 1; ch <= RFCOMM_CHANNEL_MAX; ch++) {
		struct rfcomm_channel *srv = &servers[ch];

		if (!srv->reserved && srv->rfsock == NULL)
			return ch;
	}

	return 0;
}

static BtIOSecLevel get_sec_level(uint8_t flags)
{
	/*
	 * HAL_SOCK_FLAG_AUTH should require MITM but in our case setting
	 * security to BT_IO_SEC_HIGH would also require 16-digits PIN code
	 * for pre-2.1 devices which is not what Android expects. For this
	 * reason we ignore this flag to not break apps which use "secure"
	 * sockets (have both auth and encrypt flags set, there is no public
	 * API in Android which should provide proper high security socket).
	 */
	return flags & HAL_SOCK_FLAG_ENCRYPT ? BT_IO_SEC_MEDIUM :
							BT_IO_SEC_LOW;
}

static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
						uint8_t flags, int *hal_sock)
{
	const struct profile_info *profile;
	struct rfcomm_sock *rfsock = NULL;
	BtIOSecLevel sec_level;
	GIOChannel *io, *jv_io;
	GIOCondition cond;
	GError *err = NULL;
	guint id;
	uuid_t uu;
	char uuid_str[32];

	sdp_uuid128_create(&uu, uuid);
	sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str));

	DBG("chan %d flags 0x%02x uuid %s name %s", chan, flags, uuid_str,
									name);

	if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) ||
			(chan > RFCOMM_CHANNEL_MAX)) {
		error("Invalid rfcomm listen params");
		return HAL_STATUS_INVALID;
	}

	profile = get_profile_by_uuid(uuid);
	if (!profile) {
		sec_level = get_sec_level(flags);
	} else {
		if (!profile->create_record)
			return HAL_STATUS_INVALID;

		chan = profile->channel;
		sec_level = profile->sec_level;
	}

	if (chan <= 0)
		chan = find_free_channel();

	if (!chan) {
		error("No free channels");
		return HAL_STATUS_BUSY;
	}

	if (servers[chan].rfsock != NULL) {
		error("Channel already registered (%d)", chan);
		return HAL_STATUS_BUSY;
	}

	DBG("chan %d sec_level %d", chan, sec_level);

	rfsock = create_rfsock(-1, hal_sock);
	if (!rfsock)
		return HAL_STATUS_FAILED;

	rfsock->channel = chan;

	io = bt_io_listen(accept_cb, NULL, rfsock, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_CHANNEL, chan,
				BT_IO_OPT_SEC_LEVEL, sec_level,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("Failed listen: %s", err->message);
		g_error_free(err);
		goto failed;
	}

	rfsock->bt_sock = g_io_channel_unix_get_fd(io);

	g_io_channel_set_close_on_unref(io, FALSE);
	g_io_channel_unref(io);

	/* Handle events from Android */
	cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	jv_io = g_io_channel_unix_new(rfsock->jv_sock);
	id = g_io_add_watch_full(jv_io, G_PRIORITY_HIGH, cond,
					jv_sock_server_event_cb, rfsock,
					NULL);
	g_io_channel_unref(jv_io);

	rfsock->jv_watch = id;

	DBG("rfsock %p bt_sock %d jv_sock %d hal_sock %d", rfsock,
								rfsock->bt_sock,
								rfsock->jv_sock,
								*hal_sock);

	if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) {
		error("Error sending RFCOMM channel");
		goto failed;
	}

	rfsock->service_handle = sdp_service_register(chan, uuid, profile,
									name);

	servers[chan].rfsock = rfsock;

	return HAL_STATUS_SUCCESS;

failed:

	cleanup_rfsock(rfsock);
	close(*hal_sock);
	return HAL_STATUS_FAILED;
}

static void handle_listen(const void *buf, uint16_t len)
{
	const struct hal_cmd_socket_listen *cmd = buf;
	uint8_t status;
	int hal_sock;

	switch (cmd->type) {
	case HAL_SOCK_RFCOMM:
		status = rfcomm_listen(cmd->channel, cmd->name, cmd->uuid,
							cmd->flags, &hal_sock);
		break;
	case HAL_SOCK_SCO:
	case HAL_SOCK_L2CAP:
		status = HAL_STATUS_UNSUPPORTED;
		break;
	default:
		status = HAL_STATUS_INVALID;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		goto failed;

	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
							0, NULL, hal_sock);
	close(hal_sock);
	return;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
									status);
}

static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
{
	struct hal_sock_connect_signal cmd;
	int len;

	DBG("");

	memset(&cmd, 0, sizeof(cmd));
	cmd.size = sizeof(cmd);
	bdaddr2android(bdaddr, cmd.bdaddr);
	cmd.channel = rfsock->channel;
	cmd.status = 0;

	len = write(rfsock->jv_sock, &cmd, sizeof(cmd));
	if (len < 0) {
		error("%s", strerror(errno));
		return false;
	}

	if (len != sizeof(cmd)) {
		error("Error sending connect signal");
		return false;
	}

	return true;
}

static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
	struct rfcomm_sock *rfsock = user_data;
	bdaddr_t *dst = &rfsock->dst;
	GIOChannel *jv_io;
	char address[18];
	guint id;
	GIOCondition cond;

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

	ba2str(dst, address);
	DBG("Connected to %s on channel %d (rfsock %p)", address,
						rfsock->channel, rfsock);

	if (!sock_send_connect(rfsock, dst))
		goto fail;

	/* Handle events from Android */
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	jv_io = g_io_channel_unix_new(rfsock->jv_sock);
	id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, rfsock);
	g_io_channel_unref(jv_io);

	rfsock->jv_watch = id;

	/* Handle rfcomm events */
	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
	id = g_io_add_watch(io, cond, bt_sock_event_cb, rfsock);
	g_io_channel_set_close_on_unref(io, FALSE);

	rfsock->bt_watch = id;

	return;
fail:
	connections = g_list_remove(connections, rfsock);
	cleanup_rfsock(rfsock);
}

static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan)
{
	GIOChannel *io;
	GError *gerr = NULL;

	DBG("rfsock %p sec_level %d chan %d", rfsock, rfsock->sec_level, chan);

	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
				BT_IO_OPT_CHANNEL, chan,
				BT_IO_OPT_SEC_LEVEL, rfsock->sec_level,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("Failed connect: %s", gerr->message);
		g_error_free(gerr);
		return false;
	}

	g_io_channel_set_close_on_unref(io, FALSE);
	g_io_channel_unref(io);

	if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) {
		error("Error sending RFCOMM channel");
		return false;
	}

	rfsock->bt_sock = g_io_channel_unix_get_fd(io);
	rfsock_set_buffer(rfsock);
	rfsock->channel = chan;
	connections = g_list_append(connections, rfsock);

	return true;
}

static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	sdp_list_t *list;
	int chan;

	DBG("");

	if (err < 0) {
		error("Unable to get SDP record: %s", strerror(-err));
		goto fail;
	}

	if (!recs || !recs->data) {
		error("No SDP records found");
		goto fail;
	}

	for (list = recs; list != NULL; list = list->next) {
		sdp_record_t *rec = list->data;
		sdp_list_t *protos;

		if (sdp_get_access_protos(rec, &protos) < 0) {
			error("Unable to get proto list");
			goto fail;
		}

		chan = sdp_get_proto_port(protos, RFCOMM_UUID);

		sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free,
									NULL);
		sdp_list_free(protos, NULL);

		if (chan)
			break;
	}

	if (chan <= 0) {
		error("Could not get RFCOMM channel %d", chan);
		goto fail;
	}

	DBG("Got RFCOMM channel %d", chan);

	if (do_rfcomm_connect(rfsock, chan))
		return;
fail:
	cleanup_rfsock(rfsock);
}

static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
					const uint8_t *uuid, uint8_t flags,
					int *hal_sock)
{
	struct rfcomm_sock *rfsock;
	char address[18];
	uuid_t uu;
	char uuid_str[32];

	sdp_uuid128_create(&uu, uuid);
	sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str));
	ba2str(addr, address);

	DBG("addr %s chan %d flags 0x%02x uuid %s", address, chan, flags,
								uuid_str);

	if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) ||
						!bacmp(addr, BDADDR_ANY)) {
		error("Invalid rfcomm connect params");
		return HAL_STATUS_INVALID;
	}

	rfsock = create_rfsock(-1, hal_sock);
	if (!rfsock)
		return HAL_STATUS_FAILED;

	DBG("rfsock %p jv_sock %d hal_sock %d", rfsock, rfsock->jv_sock,
							*hal_sock);

	rfsock->sec_level = get_sec_level(flags);

	bacpy(&rfsock->dst, addr);

	if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid))) {
		if (!do_rfcomm_connect(rfsock, chan))
			goto failed;
	} else {

		if (bt_search_service(&adapter_addr, &rfsock->dst, &uu,
					sdp_search_cb, rfsock, NULL, 0) < 0) {
			error("Failed to search SDP records");
			goto failed;
		}
	}

	return HAL_STATUS_SUCCESS;

failed:
	cleanup_rfsock(rfsock);
	close(*hal_sock);
	return HAL_STATUS_FAILED;
}

static void handle_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_socket_connect *cmd = buf;
	bdaddr_t bdaddr;
	uint8_t status;
	int hal_sock;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	switch (cmd->type) {
	case HAL_SOCK_RFCOMM:
		status = connect_rfcomm(&bdaddr, cmd->channel, cmd->uuid,
							cmd->flags, &hal_sock);
		break;
	case HAL_SOCK_SCO:
	case HAL_SOCK_L2CAP:
		status = HAL_STATUS_UNSUPPORTED;
		break;
	default:
		status = HAL_STATUS_INVALID;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		goto failed;

	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
							0, NULL, hal_sock);
	close(hal_sock);
	return;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
									status);

}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_SOCKET_LISTEN */
	{ handle_listen, false, sizeof(struct hal_cmd_socket_listen) },
	/* HAL_OP_SOCKET_CONNECT */
	{ handle_connect, false, sizeof(struct hal_cmd_socket_connect) },
};

void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	size_t i;

	DBG("");

	/*
	 * make sure channels assigned for profiles are reserved and not used
	 * for app services
	 */
	for (i = 0; i < G_N_ELEMENTS(profiles); i++)
		if (profiles[i].channel)
			servers[profiles[i].channel].reserved = true;

	bacpy(&adapter_addr, addr);

	hal_ipc = ipc;
	ipc_register(hal_ipc, HAL_SERVICE_ID_SOCKET, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));
}

void bt_socket_unregister(void)
{
	int ch;

	DBG("");

	g_list_free_full(connections, cleanup_rfsock);

	for (ch = 0; ch <= RFCOMM_CHANNEL_MAX; ch++)
		if (servers[ch].rfsock)
			cleanup_rfsock(servers[ch].rfsock);

	memset(servers, 0, sizeof(servers));

	ipc_unregister(hal_ipc, HAL_SERVICE_ID_SOCKET);
	hal_ipc = NULL;
}
