/*
 *
 *  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;
}
