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

#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/sdp-client.h"
#include "src/uuid-helper.h"
#include "src/shared/hfp.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"
#include "btio/btio.h"
#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "handsfree.h"
#include "bluetooth.h"
#include "src/log.h"
#include "utils.h"
#include "sco-msg.h"
#include "sco.h"

#define HSP_AG_CHANNEL 12
#define HFP_AG_CHANNEL 13

#define HFP_AG_FEAT_3WAY	0x00000001
#define HFP_AG_FEAT_ECNR	0x00000002
#define HFP_AG_FEAT_VR		0x00000004
#define HFP_AG_FEAT_INBAND	0x00000008
#define HFP_AG_FEAT_VTAG	0x00000010
#define HFP_AG_FEAT_REJ_CALL	0x00000020
#define HFP_AG_FEAT_ECS		0x00000040
#define HFP_AG_FEAT_ECC		0x00000080
#define HFP_AG_FEAT_EXT_ERR	0x00000100
#define HFP_AG_FEAT_CODEC	0x00000200

#define HFP_HF_FEAT_ECNR	0x00000001
#define HFP_HF_FEAT_3WAY	0x00000002
#define HFP_HF_FEAT_CLI		0x00000004
#define HFP_HF_FEAT_VR		0x00000008
#define HFP_HF_FEAT_RVC		0x00000010
#define HFP_HF_FEAT_ECS		0x00000020
#define HFP_HF_FEAT_ECC		0x00000040
#define HFP_HF_FEAT_CODEC	0x00000080

#define HFP_AG_FEATURES (HFP_AG_FEAT_3WAY | HFP_AG_FEAT_ECNR |\
				HFP_AG_FEAT_VR | HFP_AG_FEAT_REJ_CALL |\
				HFP_AG_FEAT_ECS | HFP_AG_FEAT_EXT_ERR)

#define HFP_AG_CHLD "0,1,2,3"

/* offsets in indicators table, should be incremented when sending CIEV */
#define IND_SERVICE	0
#define IND_CALL	1
#define IND_CALLSETUP	2
#define IND_CALLHELD	3
#define IND_SIGNAL	4
#define IND_ROAM	5
#define IND_BATTCHG	6
#define IND_COUNT	(IND_BATTCHG + 1)

#define RING_TIMEOUT 2

#define CVSD_OFFSET 0
#define MSBC_OFFSET 1
#define CODECS_COUNT (MSBC_OFFSET + 1)

#define CODEC_ID_CVSD 0x01
#define CODEC_ID_MSBC 0x02

struct indicator {
	const char *name;
	int min;
	int max;
	int val;
	bool always_active;
	bool active;
};

struct hfp_codec {
	uint8_t type;
	bool local_supported;
	bool remote_supported;
};

struct hf_device {
	bdaddr_t bdaddr;
	uint8_t state;
	uint8_t audio_state;
	uint32_t features;

	bool clip_enabled;
	bool cmee_enabled;
	bool ccwa_enabled;
	bool indicators_enabled;
	struct indicator inds[IND_COUNT];
	int num_active;
	int num_held;
	int setup_state;
	bool call_hanging_up;

	uint8_t negotiated_codec;
	uint8_t proposed_codec;
	struct hfp_codec codecs[CODECS_COUNT];

	guint ring;
	char *clip;
	bool hsp;

	struct hfp_gw *gw;
	guint delay_sco;
};

static const struct indicator inds_defaults[] = {
		{ "service",   0, 1, 0, false, true },
		{ "call",      0, 1, 0, true, true },
		{ "callsetup", 0, 3, 0, true, true },
		{ "callheld",  0, 2, 0, true, true },
		{ "signal",    0, 5, 0, false, true },
		{ "roam",      0, 1, 0, false, true },
		{ "battchg",   0, 5, 0, false, true },
};

static const struct hfp_codec codecs_defaults[] = {
	{ CODEC_ID_CVSD, true, false},
	{ CODEC_ID_MSBC, false, false},
};

static struct queue *devices = NULL;

static uint32_t hfp_ag_features = 0;

static bdaddr_t adapter_addr;

static struct ipc *hal_ipc = NULL;
static struct ipc *sco_ipc = NULL;

static uint32_t hfp_record_id = 0;
static GIOChannel *hfp_server = NULL;

static uint32_t hsp_record_id = 0;
static GIOChannel *hsp_server = NULL;

static struct bt_sco *sco = NULL;

static unsigned int max_hfp_clients = 0;

static void set_state(struct hf_device *dev, uint8_t state)
{
	struct hal_ev_handsfree_conn_state ev;
	char address[18];

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

	dev->state = state;

	ba2str(&dev->bdaddr, address);
	DBG("device %s state %u", address, state);

	bdaddr2android(&dev->bdaddr, ev.bdaddr);
	ev.state = state;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_CONN_STATE, sizeof(ev), &ev);
}

static void set_audio_state(struct hf_device *dev, uint8_t state)
{
	struct hal_ev_handsfree_audio_state ev;
	char address[18];

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

	dev->audio_state = state;

	ba2str(&dev->bdaddr, address);
	DBG("device %s audio state %u", address, state);

	bdaddr2android(&dev->bdaddr, ev.bdaddr);
	ev.state = state;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_AUDIO_STATE, sizeof(ev), &ev);
}

static void init_codecs(struct hf_device *dev)
{
	memcpy(dev->codecs, codecs_defaults, sizeof(dev->codecs));

	if (hfp_ag_features & HFP_AG_FEAT_CODEC)
		dev->codecs[MSBC_OFFSET].local_supported = true;
}

static struct hf_device *device_create(const bdaddr_t *bdaddr)
{
	struct hf_device *dev;

	dev = new0(struct hf_device, 1);
	if (!dev)
		return NULL;

	bacpy(&dev->bdaddr, bdaddr);
	dev->setup_state = HAL_HANDSFREE_CALL_STATE_IDLE;
	dev->state = HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
	dev->audio_state = HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;

	memcpy(dev->inds, inds_defaults, sizeof(dev->inds));

	init_codecs(dev);

	if (!queue_push_head(devices, dev)) {
		free(dev);
		return NULL;
	}

	return dev;
}

static void device_destroy(struct hf_device *dev)
{
	hfp_gw_unref(dev->gw);

	if (dev->delay_sco)
		g_source_remove(dev->delay_sco);

	if (dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED)
		bt_sco_disconnect(sco);

	g_source_remove(dev->ring);
	g_free(dev->clip);

	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);

	queue_remove(devices, dev);
	free(dev);
}

static bool match_by_bdaddr(const void *data, const void *match_data)
{
	const struct hf_device *dev = data;
	const bdaddr_t *addr = match_data;

	return !bacmp(&dev->bdaddr, addr);
}

static struct hf_device *find_device(const bdaddr_t *bdaddr)
{
	if (!bacmp(bdaddr, BDADDR_ANY))
		return queue_peek_head(devices);

	return queue_find(devices, match_by_bdaddr, bdaddr);
}

static struct hf_device *get_device(const bdaddr_t *bdaddr)
{
	struct hf_device *dev;

	dev = find_device(bdaddr);
	if (dev)
		return dev;

	if (queue_length(devices) == max_hfp_clients)
		return NULL;

	return device_create(bdaddr);
}

static void disconnect_watch(void *user_data)
{
	struct hf_device *dev = user_data;

	DBG("");

	device_destroy(dev);
}

static void at_cmd_unknown(const char *command, void *user_data)
{
	struct hf_device *dev = user_data;
	uint8_t buf[IPC_MTU];
	struct hal_ev_handsfree_unknown_at *ev = (void *) buf;

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) {
		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
		hfp_gw_disconnect(dev->gw);
		return;
	}

	bdaddr2android(&dev->bdaddr, ev->bdaddr);

	/* copy while string including terminating NULL */
	ev->len = strlen(command) + 1;
	memcpy(ev->buf, command, ev->len);

	if (ev->len > IPC_MTU - sizeof(*ev)) {
		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
		return;
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
			HAL_EV_HANDSFREE_UNKNOWN_AT, sizeof(*ev) + ev->len, ev);
}

static void at_cmd_vgm(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_volume ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 15)
			break;

		if (hfp_context_has_next(context))
			break;

		ev.type = HAL_HANDSFREE_VOLUME_TYPE_MIC;
		ev.volume = val;
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev);

		/* Framework is not replying with result for AT+VGM */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_vgs(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_volume ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 15)
			break;

		if (hfp_context_has_next(context))
			break;

		ev.type = HAL_HANDSFREE_VOLUME_TYPE_SPEAKER;
		ev.volume = val;
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev);

		/* Framework is not replying with result for AT+VGS */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_cops(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_cops ev;
	unsigned int val;

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val != 3)
			break;

		if (!hfp_context_get_number(context, &val) || val != 0)
			break;

		if (hfp_context_has_next(context))
			break;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_COPS, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_bia(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val, i, def;
	bool tmp[IND_COUNT];

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		for (i = 0; i < IND_COUNT; i++)
			tmp[i] = dev->inds[i].active;

		i = 0;

		do {
			def = (i < IND_COUNT) ? dev->inds[i].active : 0;

			if (!hfp_context_get_number_default(context, &val, def))
				goto failed;

			if (val > 1)
				goto failed;

			if (i < IND_COUNT) {
				tmp[i] = val || dev->inds[i].always_active;
				i++;
			}
		} while (hfp_context_has_next(context));

		for (i = 0; i < IND_COUNT; i++)
			dev->inds[i].active = tmp[i];

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

failed:
	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_a(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_answer ev;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_ANSWER, sizeof(ev), &ev);

		/* Framework is not replying with result for ATA */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_SET:
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_d(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	char buf[IPC_MTU];
	struct hal_ev_handsfree_dial *ev = (void *) buf;
	int cnt;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_unquoted_string(context,
						(char *) ev->number, 255))
			break;

		bdaddr2android(&dev->bdaddr, ev->bdaddr);

		ev->number_len = strlen((char *) ev->number);

		if (ev->number[ev->number_len - 1] != ';')
			break;

		if (ev->number[0] == '>')
			cnt = strspn((char *) ev->number + 1, "0123456789") + 1;
		else
			cnt = strspn((char *) ev->number, "0123456789ABC*#+");

		if (cnt != ev->number_len - 1)
			break;

		ev->number_len++;

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_DIAL,
					sizeof(*ev) + ev->number_len, ev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_ccwa(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 1)
			break;

		if (hfp_context_has_next(context))
			break;

		dev->ccwa_enabled = val;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_chup(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_hangup ev;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_EV_HANDSFREE_HANGUP, sizeof(ev), &ev);

		/* Framework is not replying with result for AT+CHUP */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_SET:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_clcc(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_clcc ev;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_CLCC, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_SET:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_cmee(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 1)
			break;

		if (hfp_context_has_next(context))
			break;

		dev->cmee_enabled = val;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_clip(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 1)
			break;

		if (hfp_context_has_next(context))
			break;

		dev->clip_enabled = val;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_vts(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_dtmf ev;
	char str[2];

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_unquoted_string(context, str, 2))
			break;

		if (!((str[0] >= '0' && str[0] <= '9') ||
				(str[0] >= 'A' && str[0] <= 'D') ||
				str[0] == '*' || str[0] == '#'))
			break;

		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);
		ev.tone = str[0];

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_DTMF, sizeof(ev), &ev);

		/* Framework is not replying with result for AT+VTS */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_cnum(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_cnum ev;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_CNUM, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_SET:
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_binp(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;

	DBG("");

	/* TODO */

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_bldn(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_dial ev;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (hfp_context_has_next(context))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);
		ev.number_len = 0;

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_DIAL, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_SET:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_bvra(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_vr_state ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(context, &val) || val > 1)
			break;

		if (hfp_context_has_next(context))
			break;

		if (val)
			ev.state = HAL_HANDSFREE_VR_STARTED;
		else
			ev.state = HAL_HANDSFREE_VR_STOPPED;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_VR, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_nrec(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_nrec ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		/*
		 * Android HAL defines start and stop parameter for NREC
		 * callback, but spec allows HF to only disable AG's NREC
		 * feature for SLC duration. Follow spec here.
		 */
		if (!hfp_context_get_number(context, &val) || val != 0)
			break;

		if (hfp_context_has_next(context))
			break;

		ev.nrec = HAL_HANDSFREE_NREC_STOP;
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_NREC, sizeof(ev), &ev);

		/* Framework is not replying with context for AT+NREC */
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_bsir(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;

	DBG("");

	/* TODO */

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_btrh(struct hfp_context *context,
				enum hfp_gw_cmd_type type, void *user_data)
{
	struct hf_device *dev = user_data;

	DBG("");

	/* TODO */

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void disconnect_sco_cb(const bdaddr_t *addr)
{
	struct hf_device *dev;

	DBG("");

	dev = find_device(addr);
	if (!dev) {
		error("handsfree: Could not find device");
		return;
	}

	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
}

static void select_codec(struct hf_device *dev, uint8_t codec_type)
{
	uint8_t type = CODEC_ID_CVSD;
	int i;

	if (codec_type > 0) {
		type = codec_type;
		goto done;
	}

	for (i = CODECS_COUNT - 1; i >= CVSD_OFFSET; i--) {
		if (!dev->codecs[i].local_supported)
			continue;

		if (!dev->codecs[i].remote_supported)
			continue;

		type = dev->codecs[i].type;
		break;
	}

done:
	dev->proposed_codec = type;

	hfp_gw_send_info(dev->gw, "+BCS: %u", type);
}

static bool codec_negotiation_supported(struct hf_device *dev)
{
	return (dev->features & HFP_HF_FEAT_CODEC) &&
			(hfp_ag_features & HFP_AG_FEAT_CODEC);
}

static void connect_sco_cb(enum sco_status status, const bdaddr_t *addr)
{
	struct hf_device *dev;

	dev = find_device(addr);
	if (!dev) {
		error("handsfree: Connect sco failed, no device?");
		return;
	}

	if (status != SCO_STATUS_OK) {
		error("handsfree: audio connect failed");

		set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);

		if (!codec_negotiation_supported(dev))
			return;

		/* If other failed, try connecting with CVSD */
		if (dev->negotiated_codec != CODEC_ID_CVSD) {
			info("handsfree: trying fallback with CVSD");
			select_codec(dev, CODEC_ID_CVSD);
		}

		return;
	}

	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
}

static bool connect_sco(struct hf_device *dev)
{
	uint16_t voice_settings;

	if (codec_negotiation_supported(dev) &&
			dev->negotiated_codec != CODEC_ID_CVSD)
		voice_settings = BT_VOICE_TRANSPARENT;
	else
		voice_settings = BT_VOICE_CVSD_16BIT;

	if (!bt_sco_connect(sco, &dev->bdaddr, voice_settings))
		return false;

	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);

	return true;
}

static gboolean connect_sco_delayed(void *data)
{
	struct hf_device *dev = data;

	DBG("");

	dev->delay_sco = 0;

	if (connect_sco(dev))
		return FALSE;

	/*
	 * we try connect to negotiated codec. If it fails, and it isn't
	 * CVSD codec, try connect CVSD
	 */
	if (dev->negotiated_codec != CODEC_ID_CVSD)
		select_codec(dev, CODEC_ID_CVSD);

	return FALSE;
}

static void at_cmd_bcc(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_COMMAND:
		if (!codec_negotiation_supported(dev))
			break;

		if (hfp_context_has_next(result))
			break;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		/* we haven't negotiated codec, start selection */
		if (!dev->negotiated_codec) {
			select_codec(dev, 0);
			return;
		}

		/* Delay SCO connection so that OK response is send first */
		if (dev->delay_sco == 0)
			dev->delay_sco = g_idle_add(connect_sco_delayed, dev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_SET:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_bcs(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(result, &val))
			break;

		if (hfp_context_has_next(result))
			break;

		/* Remote replied with other codec. Reply with error */
		if (dev->proposed_codec != val) {
			dev->proposed_codec = 0;
			break;
		}

		dev->proposed_codec = 0;
		dev->negotiated_codec = val;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		/*
		 * Delay SCO connection so that OK response is send first,
		 * then connect with negotiated parameters.
		 */
		if (dev->delay_sco == 0)
			dev->delay_sco = g_idle_add(connect_sco_delayed, dev);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void at_cmd_ckpd(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_hsp_key_press ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(result, &val) || val != 200)
			break;

		if (hfp_context_has_next(result))
			break;

		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
						HAL_EV_HANDSFREE_HSP_KEY_PRESS,
						sizeof(ev), &ev);

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
}

static void register_post_slc_at(struct hf_device *dev)
{
	if (dev->hsp) {
		hfp_gw_register(dev->gw, at_cmd_ckpd, "+CKPD", dev, NULL);
		hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL);
		hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL);
		return;
	}

	hfp_gw_register(dev->gw, at_cmd_a, "A", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_d, "D", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_ccwa, "+CCWA", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_chup, "+CHUP", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_clcc, "+CLCC", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_cops, "+COPS", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_cmee, "+CMEE", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_clip, "+CLIP", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_vts, "+VTS", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_cnum, "+CNUM", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bia, "+BIA", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_binp, "+BINP", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bldn, "+BLDN", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bvra, "+BVRA", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_nrec, "+NREC", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bsir, "+BSIR", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_btrh, "+BTRH", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bcc, "+BCC", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bcs, "+BCS", dev, NULL);
}

static void at_cmd_cmer(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		/* mode must be =3 */
		if (!hfp_context_get_number(result, &val) || val != 3)
			break;

		/* keyp is don't care */
		if (!hfp_context_get_number(result, &val))
			break;

		/* disp is don't care */
		if (!hfp_context_get_number(result, &val))
			break;

		/* ind must be 0 or 1 */
		if (!hfp_context_get_number(result, &val) || val > 1)
			break;

		if (hfp_context_has_next(result))
			break;

		dev->indicators_enabled = val;

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		if (dev->features & HFP_HF_FEAT_3WAY)
			return;

		register_post_slc_at(dev);
		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
		return;
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
		hfp_gw_disconnect(dev->gw);
}

static void at_cmd_cind(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_cind ev;
	char *buf, *ptr;
	int len;
	unsigned int i;

	switch (type) {
	case HFP_GW_CMD_TYPE_TEST:

		/*
		 * If device supports Codec Negotiation, AT+BAC should be
		 * received first
		 */
		if (codec_negotiation_supported(dev) &&
				!dev->codecs[CVSD_OFFSET].remote_supported)
			break;

		len = strlen("+CIND:") + 1;

		for (i = 0; i < IND_COUNT; i++) {
			len += strlen("(\"\",(X,X)),");
			len += strlen(dev->inds[i].name);
		}

		buf = g_malloc(len);

		ptr = buf + sprintf(buf, "+CIND:");

		for (i = 0; i < IND_COUNT; i++) {
			ptr += sprintf(ptr, "(\"%s\",(%d%c%d)),",
					dev->inds[i].name,
					dev->inds[i].min,
					dev->inds[i].max == 1 ? ',' : '-',
					dev->inds[i].max);
		}

		ptr--;
		*ptr = '\0';

		hfp_gw_send_info(dev->gw, "%s", buf);
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		g_free(buf);
		return;
	case HFP_GW_CMD_TYPE_READ:
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_CIND, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_SET:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
		hfp_gw_disconnect(dev->gw);
}

static void at_cmd_brsf(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int feat;

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(result, &feat))
			break;

		if (hfp_context_has_next(result))
			break;

		/* TODO verify features */
		dev->features = feat;

		hfp_gw_send_info(dev->gw, "+BRSF: %u", hfp_ag_features);
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
		hfp_gw_disconnect(dev->gw);
}

static void at_cmd_chld(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	struct hal_ev_handsfree_chld ev;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!hfp_context_get_number(result, &val) || val > 3)
			break;

		/* No ECC support */
		if (hfp_context_has_next(result))
			break;

		/* value match HAL type */
		ev.chld = val;
		bdaddr2android(&dev->bdaddr, ev.bdaddr);

		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_EV_HANDSFREE_CHLD, sizeof(ev), &ev);
		return;
	case HFP_GW_CMD_TYPE_TEST:
		hfp_gw_send_info(dev->gw, "+CHLD: (%s)", HFP_AG_CHLD);
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		register_post_slc_at(dev);
		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
		return;
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
		hfp_gw_disconnect(dev->gw);
}

static struct hfp_codec *find_codec_by_type(struct hf_device *dev, uint8_t type)
{
	int i;

	for (i = 0; i < CODECS_COUNT; i++)
		if (type == dev->codecs[i].type)
			return &dev->codecs[i];

	return NULL;
}

static void at_cmd_bac(struct hfp_context *result, enum hfp_gw_cmd_type type,
								void *user_data)
{
	struct hf_device *dev = user_data;
	unsigned int val;

	DBG("");

	switch (type) {
	case HFP_GW_CMD_TYPE_SET:
		if (!codec_negotiation_supported(dev))
			goto failed;

		/* set codecs to defaults */
		init_codecs(dev);
		dev->negotiated_codec = 0;

		/*
		 * At least CVSD mandatory codec must exist
		 * HFP V1.6 4.34.1
		 */
		if (!hfp_context_get_number(result, &val) ||
							val != CODEC_ID_CVSD)
			goto failed;

		dev->codecs[CVSD_OFFSET].remote_supported = true;

		if (hfp_context_get_number(result, &val)) {
			if (val != CODEC_ID_MSBC)
				goto failed;

			dev->codecs[MSBC_OFFSET].remote_supported = true;
		}

		while (hfp_context_has_next(result)) {
			struct hfp_codec *codec;

			if (!hfp_context_get_number(result, &val))
				goto failed;

			codec = find_codec_by_type(dev, val);
			if (!codec)
				continue;

			codec->remote_supported = true;
		}

		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		if (dev->proposed_codec)
			select_codec(dev, 0);
		return;
	case HFP_GW_CMD_TYPE_TEST:
	case HFP_GW_CMD_TYPE_READ:
	case HFP_GW_CMD_TYPE_COMMAND:
		break;
	}

failed:
	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
		hfp_gw_disconnect(dev->gw);
}

static void register_slc_at(struct hf_device *dev)
{
	hfp_gw_register(dev->gw, at_cmd_brsf, "+BRSF", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_cind, "+CIND", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_cmer, "+CMER", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_chld, "+CHLD", dev, NULL);
	hfp_gw_register(dev->gw, at_cmd_bac, "+BAC", dev, NULL);
}

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

	DBG("");

	if (err) {
		error("handsfree: connect failed (%s)", err->message);
		goto failed;
	}

	dev->gw = hfp_gw_new(g_io_channel_unix_get_fd(chan));
	if (!dev->gw)
		goto failed;

	g_io_channel_set_close_on_unref(chan, FALSE);

	hfp_gw_set_close_on_unref(dev->gw, true);
	hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, dev, NULL);
	hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, dev, NULL);

	if (dev->hsp) {
		register_post_slc_at(dev);
		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
		return;
	}

	register_slc_at(dev);
	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
	return;

failed:
	g_io_channel_shutdown(chan, TRUE, NULL);
	device_destroy(dev);
}

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

	bt_io_get(chan, &err,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_DEST_BDADDR, &bdaddr,
			BT_IO_OPT_INVALID);
	if (err) {
		error("handsfree: confirm failed (%s)", err->message);
		g_error_free(err);
		goto drop;
	}

	DBG("incoming connect from %s", address);

	dev = get_device(&bdaddr);
	if (!dev) {
		error("handsfree: Failed to get device object for %s", address);
		goto drop;
	}

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
		info("handsfree: refusing connection from %s", address);
		goto drop;
	}

	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
		error("handsfree: failed to accept connection");
		device_destroy(dev);
		goto drop;
	}

	dev->hsp = GPOINTER_TO_INT(data);

	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);

	return;

drop:
	g_io_channel_shutdown(chan, TRUE, NULL);
}

static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct hf_device *dev = data;
	sdp_list_t *protos, *classes;
	GError *gerr = NULL;
	GIOChannel *io;
	uuid_t uuid;
	int channel;

	DBG("");

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

	if (!recs || !recs->data) {
		info("handsfree: no HSP SDP records found");
		goto fail;
	}

	if (sdp_get_service_classes(recs->data, &classes) < 0 || !classes) {
		error("handsfree: unable to get service classes from record");
		goto fail;
	}

	if (sdp_get_access_protos(recs->data, &protos) < 0) {
		error("handsfree: unable to get access protocols from record");
		sdp_list_free(classes, free);
		goto fail;
	}

	/* TODO read remote version? */
	/* TODO read volume control support */

	memcpy(&uuid, classes->data, sizeof(uuid));
	sdp_list_free(classes, free);

	if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 ||
			uuid.value.uuid16 != HEADSET_SVCLASS_ID) {
		sdp_list_free(protos, NULL);
		error("handsfree: invalid service record or not HSP");
		goto fail;
	}

	channel = 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 (channel <= 0) {
		error("handsfree: unable to get RFCOMM channel from record");
		goto fail;
	}

	io = bt_io_connect(connect_cb, dev, NULL, &gerr,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_CHANNEL, channel,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("handsfree: unable to connect: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	dev->hsp = true;

	g_io_channel_unref(io);
	return;

fail:
	device_destroy(dev);
}

static int sdp_search_hsp(struct hf_device *dev)
{
	uuid_t uuid;

	sdp_uuid16_create(&uuid, HEADSET_SVCLASS_ID);

	return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid,
					sdp_hsp_search_cb, dev, NULL, 0);
}

static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct hf_device *dev = data;
	sdp_list_t *protos, *classes;
	GError *gerr = NULL;
	GIOChannel *io;
	uuid_t uuid;
	int channel;

	DBG("");

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

	if (!recs || !recs->data) {
		info("handsfree: no HFP SDP records found, trying HSP");

		if (sdp_search_hsp(dev) < 0) {
			error("handsfree: HSP SDP search failed");
			goto fail;
		}

		return;
	}

	if (sdp_get_service_classes(recs->data, &classes) < 0 || !classes) {
		error("handsfree: unable to get service classes from record");
		goto fail;
	}

	if (sdp_get_access_protos(recs->data, &protos) < 0) {
		error("handsfree: unable to get access protocols from record");
		sdp_list_free(classes, free);
		goto fail;
	}

	/* TODO read remote version? */

	memcpy(&uuid, classes->data, sizeof(uuid));
	sdp_list_free(classes, free);

	if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 ||
			uuid.value.uuid16 != HANDSFREE_SVCLASS_ID) {
		sdp_list_free(protos, NULL);
		error("handsfree: invalid service record or not HFP");
		goto fail;
	}

	channel = 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 (channel <= 0) {
		error("handsfree: unable to get RFCOMM channel from record");
		goto fail;
	}

	io = bt_io_connect(connect_cb, dev, NULL, &gerr,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_CHANNEL, channel,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("handsfree: unable to connect: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	g_io_channel_unref(io);
	return;

fail:
	device_destroy(dev);
}

static int sdp_search_hfp(struct hf_device *dev)
{
	uuid_t uuid;

	sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID);

	return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid,
					sdp_hfp_search_cb, dev, NULL, 0);
}

static void handle_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_connect *cmd = buf;
	struct hf_device *dev;
	char addr[18];
	uint8_t status;
	bdaddr_t bdaddr;
	int ret;

	DBG("");

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

	dev = get_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	ba2str(&bdaddr, addr);
	DBG("connecting to %s", addr);

	/* prefer HFP over HSP */
	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
	if (ret < 0) {
		error("handsfree: SDP search failed");
		device_destroy(dev);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_CONNECT, status);
}

static void handle_disconnect(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_disconnect *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
		status = HAL_STATUS_SUCCESS;
		goto failed;
	}

	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
		device_destroy(dev);
	} else {
		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
		hfp_gw_disconnect(dev->gw);
	}

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_DISCONNECT, status);
}

static bool disconnect_sco(struct hf_device *dev)
{
	if (dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED ||
		dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING)
		return false;

	bt_sco_disconnect(sco);
	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);

	return true;
}

static bool connect_audio(struct hf_device *dev)
{
	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED)
		return false;

	/* we haven't negotiated codec, start selection */
	if (codec_negotiation_supported(dev) && !dev->negotiated_codec) {
		select_codec(dev, 0);
		return true;
	}

	return connect_sco(dev);
}

static void handle_connect_audio(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_connect_audio *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	status = connect_audio(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_CONNECT_AUDIO, status);
}

static void handle_disconnect_audio(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_disconnect_audio *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	status = disconnect_sco(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_DISCONNECT_AUDIO, status);
}

static void handle_start_vr(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_start_vr *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (dev->features & HFP_HF_FEAT_VR) {
		hfp_gw_send_info(dev->gw, "+BVRA: 1");
		status = HAL_STATUS_SUCCESS;
	} else {
		status = HAL_STATUS_FAILED;
	}

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_START_VR, status);
}

static void handle_stop_vr(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_stop_vr *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (dev->features & HFP_HF_FEAT_VR) {
		hfp_gw_send_info(dev->gw, "+BVRA: 0");
		status = HAL_STATUS_SUCCESS;
	} else {
		status = HAL_STATUS_FAILED;
	}

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_STOP_VR, status);
}

static void handle_volume_control(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_volume_control *cmd = buf;
	struct hf_device *dev;
	uint8_t status, volume;
	bdaddr_t bdaddr;

	DBG("type=%u volume=%u", cmd->type, cmd->volume);

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	volume = cmd->volume > 15 ? 15 : cmd->volume;

	switch (cmd->type) {
	case HAL_HANDSFREE_VOLUME_TYPE_MIC:
		hfp_gw_send_info(dev->gw, "+VGM: %u", volume);

		status = HAL_STATUS_SUCCESS;
		break;
	case HAL_HANDSFREE_VOLUME_TYPE_SPEAKER:
		hfp_gw_send_info(dev->gw, "+VGS: %u", volume);

		status = HAL_STATUS_SUCCESS;
		break;
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_VOLUME_CONTROL, status);
}

static void update_indicator(struct hf_device *dev, int ind, uint8_t val)
{
	DBG("ind=%u new=%u old=%u", ind, val, dev->inds[ind].val);

	if (dev->inds[ind].val == val)
		return;

	dev->inds[ind].val = val;

	if (!dev->indicators_enabled)
		return;

	if (!dev->inds[ind].active)
		return;

	/* indicator numbers in CIEV start from 1 */
	hfp_gw_send_info(dev->gw, "+CIEV: %u,%u", ind + 1, val);
}

static void device_status_notif(void *data, void *user_data)
{
	struct hf_device *dev = data;
	struct hal_cmd_handsfree_device_status_notif *cmd = user_data;

	update_indicator(dev, IND_SERVICE, cmd->state);
	update_indicator(dev, IND_ROAM, cmd->type);
	update_indicator(dev, IND_SIGNAL, cmd->signal);
	update_indicator(dev, IND_BATTCHG, cmd->battery);
}

static void handle_device_status_notif(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_device_status_notif *cmd = buf;
	uint8_t status;

	DBG("");

	if (queue_isempty(devices)) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	/* Cast cmd to void as queue api needs that */
	queue_foreach(devices, device_status_notif, (void *) cmd);

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, status);
}

static void handle_cops(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_cops_response *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	if (len != sizeof(*cmd) + cmd->len ||
			(cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) {
		error("Invalid cops response command, terminating");
		raise(SIGTERM);
		return;
	}

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	hfp_gw_send_info(dev->gw, "+COPS: 0,0,\"%.16s\"",
					cmd->len ? (char *) cmd->buf : "");

	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_COPS_RESPONSE, status);
}

static unsigned int get_callsetup(uint8_t state)
{
	switch (state) {
	case HAL_HANDSFREE_CALL_STATE_INCOMING:
		return 1;
	case HAL_HANDSFREE_CALL_STATE_DIALING:
		return 2;
	case HAL_HANDSFREE_CALL_STATE_ALERTING:
		return 3;
	default:
		return 0;
	}
}

static void handle_cind(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_cind_response *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	/* HAL doesn't provide indicators values so need to convert here */
	dev->inds[IND_SERVICE].val = cmd->svc;
	dev->inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
	dev->inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
	dev->inds[IND_CALLHELD].val = cmd->num_held ?
						(cmd->num_active ? 1 : 2) : 0;
	dev->inds[IND_SIGNAL].val = cmd->signal;
	dev->inds[IND_ROAM].val = cmd->roam;
	dev->inds[IND_BATTCHG].val = cmd->batt_chg;

	/* Order must match indicators_defaults table */
	hfp_gw_send_info(dev->gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
						dev->inds[IND_SERVICE].val,
						dev->inds[IND_CALL].val,
						dev->inds[IND_CALLSETUP].val,
						dev->inds[IND_CALLHELD].val,
						dev->inds[IND_SIGNAL].val,
						dev->inds[IND_ROAM].val,
						dev->inds[IND_BATTCHG].val);

	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_CIND_RESPONSE, status);
}

static void handle_formatted_at_resp(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_formatted_at_response *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	if (len != sizeof(*cmd) + cmd->len ||
			(cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) {
		error("Invalid formatted AT response command, terminating");
		raise(SIGTERM);
		return;
	}

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	hfp_gw_send_info(dev->gw, "%s", cmd->len ? (char *) cmd->buf : "");

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
			HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, status);
}

static void handle_at_resp(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_at_response *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (cmd->response == HAL_HANDSFREE_AT_RESPONSE_OK)
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
	else if (dev->cmee_enabled)
		hfp_gw_send_error(dev->gw, cmd->error);
	else
		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_AT_RESPONSE, status);
}

static void handle_clcc_resp(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_clcc_response *cmd = buf;
	struct hf_device *dev;
	uint8_t status;
	bdaddr_t bdaddr;
	char *number;

	if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 &&
				cmd->number[cmd->number_len - 1] != '\0')) {
		error("Invalid CLCC response command, terminating");
		raise(SIGTERM);
		return;
	}

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (!cmd->index) {
		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);

		status = HAL_STATUS_SUCCESS;
		goto done;
	}

	number = cmd->number_len ? (char *) cmd->number : "";

	switch (cmd->state) {
	case HAL_HANDSFREE_CALL_STATE_INCOMING:
	case HAL_HANDSFREE_CALL_STATE_WAITING:
	case HAL_HANDSFREE_CALL_STATE_ACTIVE:
	case HAL_HANDSFREE_CALL_STATE_HELD:
	case HAL_HANDSFREE_CALL_STATE_DIALING:
	case HAL_HANDSFREE_CALL_STATE_ALERTING:
		if (cmd->type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL &&
							number[0] != '+')
			hfp_gw_send_info(dev->gw,
					"+CLCC: %u,%u,%u,%u,%u,\"+%s\",%u",
					cmd->index, cmd->dir, cmd->state,
					cmd->mode, cmd->mpty, number,
					cmd->type);
		else
			hfp_gw_send_info(dev->gw,
					"+CLCC: %u,%u,%u,%u,%u,\"%s\",%u",
					cmd->index, cmd->dir, cmd->state,
					cmd->mode, cmd->mpty, number,
					cmd->type);

		status = HAL_STATUS_SUCCESS;
		break;
	case HAL_HANDSFREE_CALL_STATE_IDLE:
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_CLCC_RESPONSE, status);
}

static gboolean ring_cb(gpointer user_data)
{
	struct hf_device *dev = user_data;

	hfp_gw_send_info(dev->gw, "RING");

	if (dev->clip_enabled && dev->clip)
		hfp_gw_send_info(dev->gw, "%s", dev->clip);

	return TRUE;
}

static void phone_state_dialing(struct hf_device *dev, int num_active,
								int num_held)
{
	update_indicator(dev, IND_CALLSETUP, 2);

	if (num_active == 0 && num_held > 0)
		update_indicator(dev, IND_CALLHELD, 2);

	if (dev->num_active == 0 && dev->num_held == 0)
		connect_audio(dev);
}

static void phone_state_alerting(struct hf_device *dev, int num_active,
								int num_held)
{
	update_indicator(dev, IND_CALLSETUP, 3);
}

static void phone_state_waiting(struct hf_device *dev, int num_active,
					int num_held, uint8_t type,
					const uint8_t *number, int number_len)
{
	char *num;

	if (!dev->ccwa_enabled)
		return;

	num = number_len ? (char *) number : "";

	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
		hfp_gw_send_info(dev->gw, "+CCWA: \"+%s\",%u", num, type);
	else
		hfp_gw_send_info(dev->gw, "+CCWA: \"%s\",%u", num, type);

	update_indicator(dev, IND_CALLSETUP, 1);
}

static void phone_state_incoming(struct hf_device *dev, int num_active,
					int num_held, uint8_t type,
					const uint8_t *number, int number_len)
{
	char *num;

	if (dev->setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) {
		if (dev->num_active != num_active ||
						dev->num_held != num_held) {
			/*
			 * calls changed while waiting call ie. due to
			 * termination of active call
			 */
			update_indicator(dev, IND_CALLHELD,
					num_held ? (num_active ? 1 : 2) : 0);
			update_indicator(dev, IND_CALL,
						!!(num_active + num_held));
		}

		return;
	}

	if (dev->call_hanging_up)
		return;

	if (num_active > 0 || num_held > 0) {
		phone_state_waiting(dev, num_active, num_held, type, number,
								number_len);
		return;
	}

	update_indicator(dev, IND_CALLSETUP, 1);

	num = number_len ? (char *) number : "";

	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
		dev->clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
	else
		dev->clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);

	/* send first RING */
	ring_cb(dev);

	dev->ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
							RING_TIMEOUT, ring_cb,
							dev, NULL);
	if (!dev->ring) {
		g_free(dev->clip);
		dev->clip = NULL;
	}
}

static void phone_state_idle(struct hf_device *dev, int num_active,
								int num_held)
{
	if (dev->ring) {
		g_source_remove(dev->ring);
		dev->ring = 0;

		if (dev->clip) {
			g_free(dev->clip);
			dev->clip = NULL;
		}
	}

	switch (dev->setup_state) {
	case HAL_HANDSFREE_CALL_STATE_INCOMING:
		if (num_active > dev->num_active) {
			update_indicator(dev, IND_CALL, 1);

			if (dev->num_active == 0 && dev->num_held == 0)
				connect_audio(dev);
		}

		if (num_held > dev->num_held)
			update_indicator(dev, IND_CALLHELD, 1);

		update_indicator(dev, IND_CALLSETUP, 0);

		if (num_active == dev->num_active && num_held == dev->num_held)
			dev->call_hanging_up = true;

		break;
	case HAL_HANDSFREE_CALL_STATE_DIALING:
	case HAL_HANDSFREE_CALL_STATE_ALERTING:
		if (num_active > dev->num_active)
			update_indicator(dev, IND_CALL, 1);

		update_indicator(dev, IND_CALLHELD,
					num_held ? (num_active ? 1 : 2) : 0);

		update_indicator(dev, IND_CALLSETUP, 0);
		break;
	case HAL_HANDSFREE_CALL_STATE_IDLE:

		if (dev->call_hanging_up) {
			dev->call_hanging_up = false;
			return;
		}

		/* check if calls swapped */
		if (num_held != 0 && num_active != 0 &&
				dev->num_active == num_held &&
				dev->num_held == num_active) {
			/* TODO better way for forcing indicator */
			dev->inds[IND_CALLHELD].val = 0;
		} else if ((num_active > 0 || num_held > 0) &&
						dev->num_active == 0 &&
						dev->num_held == 0) {
			/*
			 * If number of active or held calls change but there
			 * was no call setup change this means that there were
			 * calls present when headset was connected.
			 */
			connect_audio(dev);
		} else if (num_active == 0 && num_held == 0) {
			disconnect_sco(dev);
		}

		update_indicator(dev, IND_CALLHELD,
					num_held ? (num_active ? 1 : 2) : 0);
		update_indicator(dev, IND_CALL, !!(num_active + num_held));
		update_indicator(dev, IND_CALLSETUP, 0);

		/* If call was terminated due to carrier lost send NO CARRIER */
		if (num_active == 0 && num_held == 0 &&
				dev->inds[IND_SERVICE].val == 0 &&
				(dev->num_active > 0 || dev->num_held > 0))
			hfp_gw_send_info(dev->gw, "NO CARRIER");

		break;
	default:
		DBG("unhandled state %u", dev->setup_state);
		break;
	}
}

static void phone_state_change(void *data, void *user_data)
{
	struct hf_device *dev = data;
	struct hal_cmd_handsfree_phone_state_change *cmd = user_data;

	switch (cmd->state) {
	case HAL_HANDSFREE_CALL_STATE_DIALING:
		phone_state_dialing(dev, cmd->num_active, cmd->num_held);
		break;
	case HAL_HANDSFREE_CALL_STATE_ALERTING:
		phone_state_alerting(dev, cmd->num_active, cmd->num_held);
		break;
	case HAL_HANDSFREE_CALL_STATE_INCOMING:
		phone_state_incoming(dev, cmd->num_active, cmd->num_held,
						cmd->type, cmd->number,
						cmd->number_len);
		break;
	case HAL_HANDSFREE_CALL_STATE_IDLE:
		phone_state_idle(dev, cmd->num_active, cmd->num_held);
		break;
	default:
		DBG("unhandled new state %u (current state %u)", cmd->state,
							dev->setup_state);

		return;
	}

	dev->num_active = cmd->num_active;
	dev->num_held = cmd->num_held;
	dev->setup_state = cmd->state;

}

static void handle_phone_state_change(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_phone_state_change *cmd = buf;
	uint8_t status;

	if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 &&
				cmd->number[cmd->number_len - 1] != '\0')) {
		error("Invalid phone state change command, terminating");
		raise(SIGTERM);
		return;
	}

	DBG("active=%u hold=%u state=%u", cmd->num_active, cmd->num_held,
								cmd->state);

	if (queue_isempty(devices)) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	/* Cast cmd to void as queue api needs that */
	queue_foreach(devices, phone_state_change, (void *) cmd);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_PHONE_STATE_CHANGE, status);
}

static void handle_configure_wbs(const void *buf, uint16_t len)
{
	const struct hal_cmd_handsfree_configure_wbs *cmd = buf;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	uint8_t status;

	if (!(hfp_ag_features & HFP_AG_FEAT_CODEC)) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	switch (cmd->config) {
	case HAL_HANDSFREE_WBS_NO:
		dev->codecs[MSBC_OFFSET].local_supported = false;
		break;
	case HAL_HANDSFREE_WBS_YES:
		dev->codecs[MSBC_OFFSET].local_supported = true;
		break;
	case HAL_HANDSFREE_WBS_NONE:
		/* TODO */
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

	/*
	 * cleanup negotiated codec if WBS support was changed, it will be
	 * renegotiated on next audio connection based on currently supported
	 * codecs
	 */
	dev->negotiated_codec = 0;
	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_CONFIGURE_WBS, status);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_HANDSFREE_CONNECT */
	{ handle_connect, false,
		sizeof(struct hal_cmd_handsfree_connect) },
	/* HAL_OP_HANDSFREE_DISCONNECT */
	{ handle_disconnect, false,
		sizeof(struct hal_cmd_handsfree_disconnect) },
	/* HAL_OP_HANDSFREE_CONNECT_AUDIO */
	{ handle_connect_audio, false,
		sizeof(struct hal_cmd_handsfree_connect_audio) },
	/* HAL_OP_HANDSFREE_DISCONNECT_AUDIO */
	{ handle_disconnect_audio, false,
		sizeof(struct hal_cmd_handsfree_disconnect_audio) },
	/* define HAL_OP_HANDSFREE_START_VR */
	{ handle_start_vr, false, sizeof(struct hal_cmd_handsfree_start_vr) },
	/* define HAL_OP_HANDSFREE_STOP_VR */
	{ handle_stop_vr, false, sizeof(struct hal_cmd_handsfree_stop_vr) },
	/* HAL_OP_HANDSFREE_VOLUME_CONTROL */
	{ handle_volume_control, false,
		sizeof(struct hal_cmd_handsfree_volume_control) },
	/* HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF */
	{ handle_device_status_notif, false,
		sizeof(struct hal_cmd_handsfree_device_status_notif) },
	/* HAL_OP_HANDSFREE_COPS_RESPONSE */
	{ handle_cops, true,
		sizeof(struct hal_cmd_handsfree_cops_response) },
	/* HAL_OP_HANDSFREE_CIND_RESPONSE */
	{ handle_cind, false,
		sizeof(struct hal_cmd_handsfree_cind_response) },
	/* HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE */
	{ handle_formatted_at_resp, true,
		sizeof(struct hal_cmd_handsfree_formatted_at_response) },
	/* HAL_OP_HANDSFREE_AT_RESPONSE */
	{ handle_at_resp, false,
		sizeof(struct hal_cmd_handsfree_at_response) },
	/* HAL_OP_HANDSFREE_CLCC_RESPONSE */
	{ handle_clcc_resp, true,
		sizeof(struct hal_cmd_handsfree_clcc_response) },
	/* HAL_OP_HANDSFREE_PHONE_STATE_CHANGE */
	{ handle_phone_state_change, true,
		sizeof(struct hal_cmd_handsfree_phone_state_change) },
	/* HAL_OP_HANDSFREE_CONFIGURE_WBS */
	{ handle_configure_wbs, false,
		sizeof(struct hal_cmd_handsfree_configure_wbs) },
};

static sdp_record_t *headset_ag_record(void)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
	uuid_t l2cap_uuid, rfcomm_uuid;
	sdp_profile_desc_t profile;
	sdp_list_t *aproto, *proto[2];
	sdp_record_t *record;
	sdp_data_t *channel;
	uint8_t netid = 0x01;
	sdp_data_t *network;
	uint8_t ch = HSP_AG_CHANNEL;

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

	network = sdp_data_alloc(SDP_UINT8, &netid);
	if (!network) {
		sdp_record_free(record);
		return NULL;
	}

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

	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &svclass_uuid);
	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
	profile.version = 0x0102;
	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, &ch);
	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_set_info_attr(record, "Voice Gateway", NULL, NULL);

	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], 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 bool confirm_sco_cb(const bdaddr_t *addr, uint16_t *voice_settings)
{
	char address[18];
	struct hf_device *dev;

	ba2str(addr, address);

	DBG("incoming SCO connection from %s", address);

	dev = find_device(addr);
	if (!dev || dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) {
		error("handsfree: audio connection from %s rejected", address);
		return false;
	}

	/* If HF initiate SCO there must be no WBS used */
	*voice_settings = 0;

	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
	return true;
}

static bool enable_hsp_ag(void)
{
	sdp_record_t *rec;
	GError *err = NULL;

	DBG("");

	hsp_server =  bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(true),
					NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_CHANNEL, HSP_AG_CHANNEL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_INVALID);
	if (!hsp_server) {
		error("Failed to listen on Headset rfcomm: %s", err->message);
		g_error_free(err);
		return false;
	}

	rec = headset_ag_record();
	if (!rec) {
		error("Failed to allocate Headset record");
		goto failed;
	}

	if (bt_adapter_add_record(rec, 0) < 0) {
		error("Failed to register Headset record");
		sdp_record_free(rec);
		goto failed;
	}

	hsp_record_id = rec->handle;
	return true;

failed:
	g_io_channel_shutdown(hsp_server, TRUE, NULL);
	g_io_channel_unref(hsp_server);
	hsp_server = NULL;

	return false;
}

static void cleanup_hsp_ag(void)
{
	if (hsp_server) {
		g_io_channel_shutdown(hsp_server, TRUE, NULL);
		g_io_channel_unref(hsp_server);
		hsp_server = NULL;
	}

	if (hsp_record_id > 0) {
		bt_adapter_remove_record(hsp_record_id);
		hsp_record_id = 0;
	}
}

static sdp_record_t *hfp_ag_record(void)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
	uuid_t l2cap_uuid, rfcomm_uuid;
	sdp_profile_desc_t profile;
	sdp_list_t *aproto, *proto[2];
	sdp_record_t *record;
	sdp_data_t *channel, *features;
	uint8_t netid = 0x01;
	uint16_t sdpfeat;
	sdp_data_t *network;
	uint8_t ch = HFP_AG_CHANNEL;

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

	network = sdp_data_alloc(SDP_UINT8, &netid);
	if (!network) {
		sdp_record_free(record);
		return NULL;
	}

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

	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &svclass_uuid);
	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
	profile.version = 0x0106;
	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, &ch);
	proto[1] = sdp_list_append(proto[1], channel);
	apseq = sdp_list_append(apseq, proto[1]);

	/* Codec Negotiation bit in SDP feature is different then in BRSF */
	sdpfeat = hfp_ag_features & 0x0000003F;
	if (hfp_ag_features & HFP_AG_FEAT_CODEC)
		sdpfeat |= 0x00000020;
	else
		sdpfeat &= ~0x00000020;

	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);

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

	sdp_set_info_attr(record, "Hands-Free Audio Gateway", NULL, NULL);

	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);

	sdp_data_free(channel);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], 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 bool enable_hfp_ag(void)
{
	sdp_record_t *rec;
	GError *err = NULL;

	DBG("");

	if (hfp_server)
		return false;

	hfp_server =  bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(false),
					NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_CHANNEL, HFP_AG_CHANNEL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_INVALID);
	if (!hfp_server) {
		error("Failed to listen on Handsfree rfcomm: %s", err->message);
		g_error_free(err);
		return false;
	}

	rec = hfp_ag_record();
	if (!rec) {
		error("Failed to allocate Handsfree record");
		goto failed;
	}

	if (bt_adapter_add_record(rec, 0) < 0) {
		error("Failed to register Handsfree record");
		sdp_record_free(rec);
		goto failed;
	}

	hfp_record_id = rec->handle;
	return true;

failed:
	g_io_channel_shutdown(hfp_server, TRUE, NULL);
	g_io_channel_unref(hfp_server);
	hfp_server = NULL;

	return false;
}

static void cleanup_hfp_ag(void)
{
	if (hfp_server) {
		g_io_channel_shutdown(hfp_server, TRUE, NULL);
		g_io_channel_unref(hfp_server);
		hfp_server = NULL;
	}

	if (hfp_record_id > 0) {
		bt_adapter_remove_record(hfp_record_id);
		hfp_record_id = 0;
	}
}

static void bt_sco_get_fd(const void *buf, uint16_t len)
{
	const struct sco_cmd_get_fd *cmd = buf;
	struct sco_rsp_get_fd rsp;
	struct hf_device *dev;
	bdaddr_t bdaddr;
	int fd;

	DBG("");

	android2bdaddr(cmd->bdaddr, &bdaddr);

	dev = find_device(&bdaddr);
	if (!dev || !bt_sco_get_fd_and_mtu(sco, &fd, &rsp.mtu))
		goto failed;

	DBG("fd %d mtu %u", fd, rsp.mtu);

	ipc_send_rsp_full(sco_ipc, SCO_SERVICE_ID, SCO_OP_GET_FD,
							sizeof(rsp), &rsp, fd);

	return;

failed:
	ipc_send_rsp(sco_ipc, SCO_SERVICE_ID, SCO_OP_STATUS, SCO_STATUS_FAILED);
}

static const struct ipc_handler sco_handlers[] = {
	/* SCO_OP_GET_FD */
	{ bt_sco_get_fd, false, 0 }
};

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

	ipc_cleanup(sco_ipc);
	sco_ipc = NULL;
}

static bool bt_sco_register(ipc_disconnect_cb disconnect)
{
	DBG("");

	sco_ipc = ipc_init(BLUEZ_SCO_SK_PATH, sizeof(BLUEZ_SCO_SK_PATH),
				SCO_SERVICE_ID, false, disconnect, NULL);
	if (!sco_ipc)
		return false;

	ipc_register(sco_ipc, SCO_SERVICE_ID, sco_handlers,
						G_N_ELEMENTS(sco_handlers));

	return true;
}

bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode,
								int max_clients)
{
	DBG("mode 0x%x max_clients %d", mode, max_clients);

	bacpy(&adapter_addr, addr);

	if (max_clients < 1)
		return false;

	devices = queue_new();
	if (!devices)
		return false;

	if (!enable_hsp_ag())
		goto failed_queue;

	sco = bt_sco_new(addr);
	if (!sco)
		goto failed_hsp;

	bt_sco_set_confirm_cb(sco, confirm_sco_cb);
	bt_sco_set_connect_cb(sco, connect_sco_cb);
	bt_sco_set_disconnect_cb(sco, disconnect_sco_cb);

	if (mode == HAL_MODE_HANDSFREE_HSP_ONLY)
		goto done;

	hfp_ag_features = HFP_AG_FEATURES;

	if (mode == HAL_MODE_HANDSFREE_HFP_WBS)
		hfp_ag_features |= HFP_AG_FEAT_CODEC;

	if (enable_hfp_ag())
		goto done;

	bt_sco_unref(sco);
	sco = NULL;
	hfp_ag_features = 0;
failed_hsp:
	cleanup_hsp_ag();
failed_queue:
	queue_destroy(devices, NULL);
	devices = NULL;

	return false;

done:
	hal_ipc = ipc;
	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	bt_sco_register(NULL);

	max_hfp_clients = max_clients;

	return true;
}

void bt_handsfree_unregister(void)
{
	DBG("");

	bt_sco_unregister();
	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE);
	hal_ipc = NULL;

	cleanup_hfp_ag();
	cleanup_hsp_ag();
	bt_sco_unref(sco);
	sco = NULL;

	hfp_ag_features = 0;

	queue_destroy(devices, (queue_destroy_func_t) device_destroy);
	devices = NULL;

	max_hfp_clients = 0;
}
