/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <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 "bluetooth.h"
#include "log.h"
#include "hal-msg.h"
#include "hal-ipc.h"
#include "ipc.h"
#include "utils.h"
#include "socket.h"

#define SPP_DEFAULT_CHANNEL	3
#define OPP_DEFAULT_CHANNEL	9
#define PBAP_DEFAULT_CHANNEL	15
#define MAS_DEFAULT_CHANNEL	16

#define SVC_HINT_OBEX 0x10

static bdaddr_t adapter_addr;

/* Simple list of RFCOMM server sockets */
GList *servers = NULL;

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

struct rfcomm_sock {
	int fd;		/* descriptor for communication with Java framework */
	int real_sock;	/* real RFCOMM socket */
	int channel;	/* RFCOMM channel */

	guint rfcomm_watch;
	guint stack_watch;

	bdaddr_t dst;
	uint32_t service_handle;

	const struct profile_info *profile;
};

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

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

	rfsock = g_new0(struct rfcomm_sock, 1);
	rfsock->fd = fds[0];
	*hal_fd = fds[1];
	rfsock->real_sock = sock;

	return rfsock;
}

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

	DBG("rfsock: %p fd %d real_sock %d chan %u",
		rfsock, rfsock->fd, rfsock->real_sock, rfsock->channel);

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

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

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

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

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

	g_free(rfsock);
}

static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
{
	const char *service_name = "OBEX Object Push";
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
	sdp_profile_desc_t profile[1];
	sdp_list_t *aproto, *proto[3];
	uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
	void *dtds[sizeof(formats)], *values[sizeof(formats)];
	unsigned int i;
	uint8_t dtd = SDP_UINT8;
	sdp_data_t *sflist;
	sdp_data_t *channel;
	sdp_record_t *record;

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

	record->handle =  sdp_next_handle();

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

	sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &opush_uuid);
	sdp_set_service_classes(record, svclass_id);

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

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
	apseq = 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);
	apseq = sdp_list_append(apseq, proto[1]);

	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
	proto[2] = sdp_list_append(NULL, &obex_uuid);
	apseq = sdp_list_append(apseq, proto[2]);

	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);

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

	if (svc_name)
		service_name = svc_name;

	sdp_set_info_attr(record, service_name, NULL, NULL);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(proto[2], NULL);
	sdp_list_free(apseq, NULL);
	sdp_list_free(pfseq, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(svclass_id, NULL);

	return record;
}

static sdp_record_t *create_pbap_record(uint8_t chan, const char *svc_name)
{
	const char *service_name = "OBEX Phonebook Access Server";
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, pbap_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
	sdp_profile_desc_t profile[1];
	sdp_list_t *aproto, *proto[3];
	sdp_data_t *channel;
	uint8_t formats[] = { 0x01 };
	uint8_t dtd = SDP_UINT8;
	sdp_data_t *sflist;
	sdp_record_t *record;

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

	record->handle =  sdp_next_handle();

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

	sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &pbap_uuid);
	sdp_set_service_classes(record, svclass_id);

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

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
	apseq = 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);
	apseq = sdp_list_append(apseq, proto[1]);

	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
	proto[2] = sdp_list_append(NULL, &obex_uuid);
	apseq = sdp_list_append(apseq, proto[2]);

	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);

	sflist = sdp_data_alloc(dtd, formats);
	sdp_attr_add(record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);

	if (svc_name)
		service_name = svc_name;

	sdp_set_info_attr(record, service_name, NULL, NULL);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(proto[2], NULL);
	sdp_list_free(apseq, NULL);
	sdp_list_free(pfseq, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(svclass_id, NULL);

	return record;
}

static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name)
{
	const char *service_name = "Serial Port";
	sdp_list_t *svclass_id, *apseq, *profiles, *root;
	uuid_t root_uuid, sp_uuid, l2cap, rfcomm;
	sdp_profile_desc_t profile;
	sdp_list_t *aproto, *proto[2];
	sdp_data_t *channel;
	sdp_record_t *record;

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

	record->handle =  sdp_next_handle();

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

	sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &sp_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
	profile.version = 0x0100;
	profiles = sdp_list_append(NULL, &profile);
	sdp_set_profile_descs(record, profiles);

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

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

	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);

	sdp_add_lang_attr(record);

	if (svc_name)
		service_name = svc_name;

	sdp_set_info_attr(record, service_name, "BlueZ", "COM Port");

	sdp_set_url_attr(record, "http://www.bluez.org/",
			"http://www.bluez.org/", "http://www.bluez.org/");

	sdp_set_service_id(record, sp_uuid);
	sdp_set_service_ttl(record, 0xffff);
	sdp_set_service_avail(record, 0xff);
	sdp_set_record_state(record, 0x00001234);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(apseq, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(svclass_id, NULL);
	sdp_list_free(profiles, 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, 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 = MAS_DEFAULT_CHANNEL,
		.svc_hint = 0,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = NULL
	}, {
		.uuid = {
			0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
		},
		.channel = SPP_DEFAULT_CHANNEL,
		.svc_hint = 0,
		.sec_level = BT_IO_SEC_MEDIUM,
		.create_record = create_spp_record
	},
};

static uint32_t sdp_service_register(const struct profile_info *profile,
							const void *svc_name)
{
	sdp_record_t *record;

	if (!profile || !profile->create_record)
		return 0;

	record = profile->create_record(profile->channel, svc_name);
	if (!record)
		return 0;

	if (bt_adapter_add_record(record, profile->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 sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
								gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	unsigned char buf[1024];
	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 error: sock %d cond %d",
					g_io_channel_unix_get_fd(io), cond);
		goto fail;
	}

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

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

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

	return FALSE;
}

static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
								gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	unsigned char buf[1024];
	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 error: sock %d cond %d",
					g_io_channel_unix_get_fd(io), cond);
		goto fail;
	}

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

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

	return TRUE;
fail:
	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->fd, &cmd, sizeof(cmd), fd_accepted);
	if (len != sizeof(cmd)) {
		error("Error sending accept signal");
		return false;
	}

	return true;
}

static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
	struct rfcomm_sock *rfsock = user_data;
	struct rfcomm_sock *rfsock_acc;
	GIOChannel *io_stack;
	GError *gerr = NULL;
	bdaddr_t dst;
	char address[18];
	int sock_acc;
	int hal_fd;
	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 rfsock %p", address, rfsock);

	sock_acc = g_io_channel_unix_get_fd(io);
	rfsock_acc = create_rfsock(sock_acc, &hal_fd);
	if (!rfsock_acc) {
		g_io_channel_shutdown(io, TRUE, NULL);
		return;
	}

	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
		rfsock->fd, rfsock->real_sock, rfsock->channel,
		sock_acc);

	if (!sock_send_accept(rfsock, &dst, hal_fd)) {
		cleanup_rfsock(rfsock_acc);
		return;
	}

	connections = g_list_append(connections, rfsock_acc);

	/* Handle events from Android */
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	io_stack = g_io_channel_unix_new(rfsock_acc->fd);
	id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock_acc);
	g_io_channel_unref(io_stack);

	rfsock_acc->stack_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, sock_rfcomm_event_cb, rfsock_acc);
	g_io_channel_set_close_on_unref(io, FALSE);

	rfsock_acc->rfcomm_watch = id;

	DBG("rfsock %p rfsock_acc %p stack_watch %d rfcomm_watch %d",
		rfsock, rfsock_acc, rfsock_acc->stack_watch,
		rfsock_acc->rfcomm_watch);
}

static void handle_listen(const void *buf, uint16_t len)
{
	const struct hal_cmd_sock_listen *cmd = buf;
	const struct profile_info *profile;
	struct rfcomm_sock *rfsock = NULL;
	BtIOSecLevel sec_level;
	GIOChannel *io;
	GError *err = NULL;
	int hal_fd = -1;
	int chan;

	DBG("");

	profile = get_profile_by_uuid(cmd->uuid);
	if (!profile) {
		if (!cmd->channel)
			goto failed;

		chan = cmd->channel;
		sec_level = BT_IO_SEC_MEDIUM;
	} else {
		chan = profile->channel;
		sec_level = profile->sec_level;
	}

	DBG("rfcomm channel %d svc_name %s", chan, cmd->name);

	rfsock = create_rfsock(-1, &hal_fd);
	if (!rfsock)
		goto failed;

	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->real_sock = g_io_channel_unix_get_fd(io);

	g_io_channel_unref(io);

	DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
								hal_fd);

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

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

	servers = g_list_append(servers, rfsock);

	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN, 0, NULL,
									hal_fd);
	close(hal_fd);
	return;

failed:
	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN,
							HAL_STATUS_FAILED);

	if (rfsock)
		cleanup_rfsock(rfsock);

	if (hal_fd >= 0)
		close(hal_fd);
}

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->fd, &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 *io_stack;
	char address[18];
	guint id;
	GIOCondition cond;

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

	ba2str(dst, address);
	DBG("Connected to %s", address);

	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
		rfsock->fd, rfsock->real_sock, rfsock->channel,
		g_io_channel_unix_get_fd(io));

	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;
	io_stack = g_io_channel_unix_new(rfsock->fd);
	id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock);
	g_io_channel_unref(io_stack);

	rfsock->stack_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, sock_rfcomm_event_cb, rfsock);
	g_io_channel_set_close_on_unref(io, FALSE);

	rfsock->rfcomm_watch = id;

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

static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct rfcomm_sock *rfsock = data;
	BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
	GError *gerr = NULL;
	sdp_list_t *list;
	GIOChannel *io;
	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 (rfsock->profile)
		sec_level = rfsock->profile->sec_level;

	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, sec_level,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("Failed connect: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

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

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

	g_io_channel_unref(io);

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

static void handle_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_sock_connect *cmd = buf;
	struct rfcomm_sock *rfsock;
	uuid_t uuid;
	int hal_fd = -1;

	DBG("");

	rfsock = create_rfsock(-1, &hal_fd);
	if (!rfsock)
		goto failed;

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

	memset(&uuid, 0, sizeof(uuid));
	uuid.type = SDP_UUID128;
	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));

	rfsock->profile = get_profile_by_uuid(cmd->uuid);

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

	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
									hal_fd);
	close(hal_fd);
	return;

failed:
	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
							HAL_STATUS_FAILED);

	if (hal_fd >= 0)
		close(hal_fd);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_SOCK_LISTEN */
	{ handle_listen, false, sizeof(struct hal_cmd_sock_listen) },
	/* HAL_OP_SOCK_CONNECT */
	{ handle_connect, false, sizeof(struct hal_cmd_sock_connect) },
};

void bt_socket_register(const bdaddr_t *addr)
{
	DBG("");

	bacpy(&adapter_addr, addr);
	ipc_register(HAL_SERVICE_ID_SOCK, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));
}

void bt_socket_unregister(void)
{
	DBG("");

	g_list_free_full(connections, cleanup_rfsock);
	g_list_free_full(servers, cleanup_rfsock);

	ipc_unregister(HAL_SERVICE_ID_SOCK);
}
