/*
 *
 *  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 uint8_t hal_mode = HAL_MODE_SOCKET_DEFAULT;

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, mtype;
	sdp_record_t *record;
	uuid_t uuid;
	int cnt, ret;

	switch (hal_mode) {
	case HAL_MODE_SOCKET_DYNAMIC_MAP:
		/*
		 * Service name for MAP is passed as XXYYname
		 * XX - instance
		 * YY - message type
		 */
		ret = sscanf(svc_name, "%02hhx%02hhx%n", &minst, &mtype, &cnt);
		if (ret != 2 || cnt != 4)
			return NULL;

		svc_name += 4;
		break;
	case HAL_MODE_SOCKET_DEFAULT:
		minst = DEFAULT_MAS_INSTANCE;
		mtype = DEFAULT_MAS_MSG_TYPE;
		break;
	default:
		return NULL;
	}

	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);
	sdp_uuid128_to_uuid(&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("");

	hal_mode = mode;

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