/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 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/shared/hfp.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"
#include "btio/btio.h"
#include "ipc.h"
#include "ipc-common.h"
#include "src/log.h"
#include "utils.h"

#include "bluetooth.h"
#include "hal-msg.h"
#include "handsfree-client.h"
#include "sco.h"

#define HFP_HF_CHANNEL 7

#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_HF_FEAT_HF_IND	0x00000100
#define HFP_HF_FEAT_ESCO_S4_T2	0x00000200

#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_FEATURES (HFP_HF_FEAT_ECNR | HFP_HF_FEAT_3WAY |\
				HFP_HF_FEAT_CLI | HFP_HF_FEAT_VR |\
				HFP_HF_FEAT_RVC | HFP_HF_FEAT_ECS |\
				HFP_HF_FEAT_ECC)

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

#define CODEC_ID_CVSD 0x01
#define CODEC_ID_MSBC 0x02

#define MAX_NUMBER_LEN 33
#define MAX_OPERATOR_NAME_LEN 17

enum hfp_indicator {
	HFP_INDICATOR_SERVICE = 0,
	HFP_INDICATOR_CALL,
	HFP_INDICATOR_CALLSETUP,
	HFP_INDICATOR_CALLHELD,
	HFP_INDICATOR_SIGNAL,
	HFP_INDICATOR_ROAM,
	HFP_INDICATOR_BATTCHG,
	HFP_INDICATOR_LAST
};

typedef void (*ciev_func_t)(uint8_t val);

struct indicator {
	uint8_t index;
	uint32_t min;
	uint32_t max;
	uint32_t val;
	ciev_func_t cb;
};

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

struct device {
	bdaddr_t bdaddr;
	struct hfp_hf *hf;
	uint8_t state;
	uint8_t audio_state;

	uint8_t negotiated_codec;
	uint32_t features;
	struct hfp_codec codecs[2];

	struct indicator ag_ind[HFP_INDICATOR_LAST];

	uint32_t chld_features;
};

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

static bdaddr_t adapter_addr;

static struct ipc *hal_ipc = NULL;

static uint32_t hfp_hf_features = 0;
static uint32_t hfp_hf_record_id = 0;
static struct queue *devices = NULL;
static GIOChannel *hfp_hf_server = NULL;

static struct bt_sco *sco = NULL;

static struct device *find_default_device(void)
{
	return queue_peek_head(devices);
}

static bool match_by_bdaddr(const void *data, const void *user_data)
{
	const bdaddr_t *addr1 = data;
	const bdaddr_t *addr2 = user_data;

	return !bacmp(addr1, addr2);
}

static struct device *find_device(const bdaddr_t *addr)
{
	return queue_find(devices, match_by_bdaddr, addr);
}

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

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

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

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

	if (!queue_push_tail(devices, dev)) {
		error("hf-client: Could not push dev on the list");
		free(dev);
		return NULL;
	}

	bacpy(&dev->bdaddr, bdaddr);
	dev->state = HAL_HF_CLIENT_CONN_STATE_DISCONNECTED;
	dev->audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED;

	init_codecs(dev);

	return dev;
}

static struct device *get_device(const bdaddr_t *addr)
{
	struct device *dev;

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

	/* We do support only one device as for now */
	if (queue_isempty(devices))
		return device_create(addr);

	return NULL;
}

static void device_set_state(struct device *dev, uint8_t state)
{
	struct hal_ev_hf_client_conn_state ev;
	char address[18];

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

	memset(&ev, 0, sizeof(ev));

	dev->state = state;

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

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

	ev.chld_feat = dev->chld_features;
	ev.peer_feat = dev->features;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_EV_HF_CLIENT_CONN_STATE, sizeof(ev), &ev);
}

static void device_destroy(struct device *dev)
{
	device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_DISCONNECTED);
	queue_remove(devices, dev);

	if (dev->hf)
		hfp_hf_unref(dev->hf);

	free(dev);
}

static void handle_disconnect(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_disconnect *cmd = buf;
	struct device *dev;
	uint32_t status;
	bdaddr_t bdaddr;
	char addr[18];

	DBG("");

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

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

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

	if (dev->state == HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (dev->state == HAL_HF_CLIENT_CONN_STATE_DISCONNECTING) {
		status = HAL_STATUS_SUCCESS;
		goto done;
	}

	if (dev->state == HAL_HF_CLIENT_CONN_STATE_CONNECTING) {
		device_destroy(dev);
		status = HAL_STATUS_SUCCESS;
		goto done;
	}

	status = hfp_hf_disconnect(dev->hf) ? HAL_STATUS_SUCCESS :
							HAL_STATUS_FAILED;

	if (status)
		device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_DISCONNECTING);

done:

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_OP_HF_CLIENT_DISCONNECT, status);
}

static void set_audio_state(struct device *dev, uint8_t state)
{
	struct hal_ev_hf_client_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_CLIENT,
				HAL_EV_HF_CLIENT_AUDIO_STATE, sizeof(ev), &ev);
}

static void bcc_cb(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	if (result != HFP_RESULT_OK)
		set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED);
}

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

static bool connect_sco(struct device *dev)
{
	if (codec_negotiation_supported(dev))
		return hfp_hf_send_command(dev->hf, bcc_cb, dev,
								"AT+BCC");

	return bt_sco_connect(sco, &dev->bdaddr, BT_VOICE_CVSD_16BIT);
}

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

	DBG("");

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

	dev = find_device(&bdaddr);
	if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED ||
		dev->audio_state != HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
		error("hf-client: Cannot create SCO, check SLC or audio state");
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (connect_sco(dev)) {
		status = HAL_STATUS_SUCCESS;
		set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING);
	} else {
		status = HAL_STATUS_FAILED;
	}

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_CONNECT_AUDIO, status);
}

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

	DBG("");

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

	dev = find_device(&bdaddr);
	if (!dev ||
		dev->audio_state == HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
		error("hf-client: Device not found or audio not connected");
		status = HAL_STATUS_FAILED;
		goto done;
	}

	bt_sco_disconnect(sco);
	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, status);
}

static void cmd_complete_cb(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct hal_ev_hf_client_command_complete ev;

	DBG("");
	memset(&ev, 0, sizeof(ev));

	switch (result) {
	case HFP_RESULT_OK:
		ev.type = HAL_HF_CLIENT_CMD_COMP_OK;
		break;
	case HFP_RESULT_NO_CARRIER:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_CARRIER;
		break;
	case HFP_RESULT_ERROR:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR;
		break;
	case HFP_RESULT_BUSY:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BUSY;
		break;
	case HFP_RESULT_NO_ANSWER:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_ANSWER;
		break;
	case HFP_RESULT_DELAYED:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_DELAYED;
		break;
	case HFP_RESULT_BLACKLISTED:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BACKLISTED;
		break;
	case HFP_RESULT_CME_ERROR:
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_CME;
		ev.cme = cme_err;
		break;
	case HFP_RESULT_CONNECT:
	case HFP_RESULT_RING:
	case HFP_RESULT_NO_DIALTONE:
	default:
		error("hf-client: Unknown error code %d", result);
		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR;
		break;
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_EV_CLIENT_COMMAND_COMPLETE, sizeof(ev), &ev);
}

static void handle_start_vr(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=1"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_OP_HF_CLIENT_START_VR, status);
}

static void handle_stop_vr(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=0"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_OP_HF_CLIENT_STOP_VR, status);
}

static void handle_volume_control(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_volume_control *cmd = buf;
	struct device *dev;
	uint8_t status;
	uint8_t vol;
	bool ret;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	/*
	 * Volume is in the range 0-15. Make sure we send correct value
	 * to remote device
	 */
	vol = cmd->volume > 15 ? 15 : cmd->volume;

	switch (cmd->type) {
	case HF_CLIENT_VOLUME_TYPE_SPEAKER:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
							"AT+VGS=%u", vol);
		break;
	case HF_CLIENT_VOLUME_TYPE_MIC:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
							"AT+VGM=%u", vol);
		break;
	default:
		ret = false;
		break;
	}

	status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_VOLUME_CONTROL,
					status);
}

static void handle_dial(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_dial *cmd = buf;
	struct device *dev;
	uint8_t status;
	bool ret;

	DBG("");

	if (len != sizeof(*cmd) + cmd->number_len)
		goto failed;

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (cmd->number_len > 0) {
		if (cmd->number[cmd->number_len - 1] != '\0')
			goto failed;

		DBG("Dialing %s", cmd->number);

		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
							"ATD%s;", cmd->number);
	} else {
		DBG("Redialing");

		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+BLDN");
	}

	status =  ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
						HAL_OP_HF_CLIENT_DIAL, status);

	return;

failed:
	error("Malformed number data, size (%u bytes), terminating", len);
	raise(SIGTERM);
}

static void handle_dial_memory(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_dial_memory *cmd = buf;
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	/* For some reason location in BT HAL is int. Therefore that check */
	if (cmd->location < 0) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL , "ATD>%d;",
								cmd->location))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_DIAL_MEMORY, status);
}

static void handle_call_action(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_call_action *cmd = buf;
	struct device *dev;
	uint8_t status;
	bool ret;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	switch (cmd->action) {
	case HAL_HF_CLIENT_ACTION_CHLD_0:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+CHLD=0");
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_1:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+CHLD=1");
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_2:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
							NULL, "AT+CHLD=2");
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_3:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+CHLD=3");
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_4:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+CHLD=4");
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_1x:
		/* Index is int in BT HAL. Let's be paranoid here */
		if (cmd->index <= 0)
			ret = false;
		else
			ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
					NULL, "AT+CHLD=1%d", cmd->index);
		break;
	case HAL_HF_CLIENT_ACTION_CHLD_2x:
		/* Index is int in BT HAL. Let's be paranoid here */
		if (cmd->index <= 0)
			ret = false;
		else
			ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
					NULL, "AT+CHLD=2%d", cmd->index);
		break;
	case HAL_HF_CLIENT_ACTION_ATA:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
									"ATA");
		break;
	case HAL_HF_CLIENT_ACTION_CHUP:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+CHUP");
		break;
	case HAL_HF_CLIENT_ACTION_BRTH_0:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+BTRH=0");
		break;
	case HAL_HF_CLIENT_ACTION_BRTH_1:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+BTRH=1");
		break;
	case HAL_HF_CLIENT_ACTION_BRTH_2:
		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
								"AT+BTRH=2");
		break;
	default:
		error("hf-client: Unknown action %d", cmd->action);
		ret = false;
		break;
	}

	status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_CALL_ACTION, status);
}

static void handle_query_current_calls(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CLCC"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS,
					status);
}

static void handle_query_operator_name(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS?"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME,
					status);
}

static void handle_retrieve_subscr_info(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	DBG("");

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CNUM"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO,
					status);
}

static void handle_send_dtmf(const void *buf, uint16_t len)
{
	const struct hal_cmd_hf_client_send_dtmf *cmd = buf;
	struct device *dev;
	uint8_t status;

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+VTS=%c",
							(char) cmd->tone))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_SEND_DTMF, status);
}

static void handle_get_last_vc_tag_num(const void *buf, uint16_t len)
{
	struct device *dev;
	uint8_t status;

	dev = find_default_device();
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BINP=1"))
		status = HAL_STATUS_SUCCESS;
	else
		status = HAL_STATUS_FAILED;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, status);
}

static void disconnect_watch(void *user_data)
{
	DBG("");

	device_destroy(user_data);
}

static void slc_error(struct device *dev)
{
	error("hf-client: Could not create SLC - dropping connection");
	hfp_hf_disconnect(dev->hf);
}

static void set_chld_feat(struct device *dev, char *feat)
{
	DBG(" %s", feat);

	if (strcmp(feat, "0") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL;
	else if (strcmp(feat, "1") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL_ACC;
	else if (strcmp(feat, "1x") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL_X;
	else if (strcmp(feat, "2") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_HOLD_ACC;
	else if (strcmp(feat, "2x") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_PRIV_X;
	else if (strcmp(feat, "3") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_MERGE;
	else if (strcmp(feat, "4") == 0)
		dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_MERGE_DETACH;
}

static void get_local_codecs_string(struct device *dev, char *buf,
								uint8_t len)
{
	int i;
	uint8_t offset;

	memset(buf, 0, len);
	offset = 0;

	for (i = 0; i < CODECS_COUNT; i++) {
		char c[8];
		int l;

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

		memset(c, 0, sizeof(c));

		l = sprintf(c, "%d,", dev->codecs[i].type);

		if (l > (len - offset - 1)) {
			error("hf-client: Codecs cannot fit into buffer");
			return;
		}

		strcat(&buf[offset], c);
		offset += l;
	}
}

static void bvra_cb(struct hfp_context *context, void *user_data)
{
	struct hal_ev_hf_client_vr_state ev;
	unsigned int val;

	if (!hfp_context_get_number(context, &val) || val > 1)
		return;

	ev.state = val ? HAL_HF_CLIENT_VR_STARTED : HAL_HF_CLIENT_VR_STOPPED;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev);
}

static void vgm_cb(struct hfp_context *context, void *user_data)
{
	struct hal_ev_hf_client_volume_changed ev;
	unsigned int val;

	if (!hfp_context_get_number(context, &val) || val > 15)
		return;

	ev.type = HF_CLIENT_VOLUME_TYPE_MIC;
	ev.volume = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev);
}

static void vgs_cb(struct hfp_context *context, void *user_data)
{
	struct hal_ev_hf_client_volume_changed ev;
	unsigned int val;

	if (!hfp_context_get_number(context, &val) || val > 15)
		return;

	ev.type = HF_CLIENT_VOLUME_TYPE_SPEAKER;
	ev.volume = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_EV_CLIENT_VOLUME_CHANGED, sizeof(ev), &ev);
}

static void brth_cb(struct hfp_context *context, void *user_data)
{
	struct hal_ev_hf_client_response_and_hold_status ev;
	unsigned int val;

	DBG("");

	if (!hfp_context_get_number(context, &val) ||
			val > HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_REJECT) {
		error("hf-client: incorrect BTRH response ");
		return;
	}

	ev.status = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS,
				sizeof(ev), &ev);
}

static void clcc_cb(struct hfp_context *context, void *user_data)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_hf_client_current_call *ev = (void *) buf;
	unsigned int val;

	DBG("");

	memset(buf, 0, sizeof(buf));

	if (!hfp_context_get_number(context, &val)) {
		error("hf-client: Could not get index");
		return;
	}

	ev->index = val;

	if (!hfp_context_get_number(context, &val) ||
				val > HAL_HF_CLIENT_DIRECTION_INCOMING) {
		error("hf-client: Could not get direction");
		return;
	}

	ev->direction = val;

	if (!hfp_context_get_number(context, &val) ||
			val > HAL_HF_CLIENT_CALL_STATE_HELD_BY_RESP_AND_HOLD) {
		error("hf-client: Could not get callstate");
		return;
	}

	ev->call_state = val;

	/* Next field is MODE but Android is not interested in this. Skip it */
	if (!hfp_context_get_number(context, &val)) {
		error("hf-client: Could not get mode");
		return;
	}

	if (!hfp_context_get_number(context, &val) || val > 1) {
		error("hf-client: Could not get multiparty");
		return;
	}

	ev->multiparty = val;

	if (hfp_context_get_string(context, (char *) &ev->number[0],
								MAX_NUMBER_LEN))
		ev->number_len = strlen((char *) ev->number) + 1;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_CURRENT_CALL,
					sizeof(*ev) + ev->number_len, ev);
}

static void ciev_cb(struct hfp_context *context, void *user_data)
{
	struct device *dev = user_data;
	unsigned int index, val;
	int i;

	DBG("");

	if (!hfp_context_get_number(context, &index))
		return;

	if (!hfp_context_get_number(context, &val))
		return;

	for (i = 0; i < HFP_INDICATOR_LAST; i++) {
		if (dev->ag_ind[i].index != index)
			continue;

		if (dev->ag_ind[i].cb) {
			dev->ag_ind[i].val = val;
			dev->ag_ind[i].cb(val);
			return;
		}
	}
}

static void cnum_cb(struct hfp_context *context, void *user_data)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_hf_client_subscriber_service_info *ev = (void *) buf;
	unsigned int service;

	DBG("");

	/* Alpha field is empty string, just skip it */
	hfp_context_skip_field(context);

	if (!hfp_context_get_string(context, (char *) &ev->name[0],
							MAX_NUMBER_LEN)) {
		error("hf-client: Could not get number");
		return;
	}

	ev->name_len = strlen((char *) &ev->name[0]) + 1;

	/* Type is not used in Android */
	hfp_context_skip_field(context);

	/* Speed field is empty string, just skip it */
	hfp_context_skip_field(context);

	if (!hfp_context_get_number(context, &service))
		return;

	switch (service) {
	case 4:
		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_VOICE;
		break;
	case 5:
		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_FAX;
		break;
	default:
		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_UNKNOWN;
		break;
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO,
					sizeof(*ev) + ev->name_len, ev);
}

static void cops_cb(struct hfp_context *context, void *user_data)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_hf_client_operator_name *ev = (void *) buf;
	unsigned int format;

	DBG("");

	/* Not interested in mode */
	hfp_context_skip_field(context);

	if (!hfp_context_get_number(context, &format))
		return;

	if (format != 0)
		info("hf-client: Not correct string format in +COSP");

	if (!hfp_context_get_string(context, (char *) &ev->name[0],
						MAX_OPERATOR_NAME_LEN)) {
		error("hf-client: incorrect COPS response");
		return;
	}

	ev->name_len = strlen((char *) &ev->name[0]) + 1;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_OPERATOR_NAME,
					sizeof(*ev) + ev->name_len, ev);
}

static void binp_cb(struct hfp_context *context, void *user_data)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_hf_client_last_void_call_tag_num *ev = (void *) buf;
	char number[33];

	DBG("");

	if (!hfp_context_get_string(context, number, sizeof(number))) {
		error("hf-client: incorrect COPS response");
		return;
	}

	ev->number_len = strlen(number) + 1;
	memcpy(ev->number, number, ev->number_len);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM,
					sizeof(*ev) + ev->number_len, ev);
}

static bool is_codec_supported_localy(struct device *dev, uint8_t codec)
{
	int i;

	for (i = 0; i < CODECS_COUNT; i++) {
		if (dev->codecs[i].type != codec)
			continue;

		return dev->codecs[i].local_supported;
	}

	return false;
}

static void bcs_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	if (result != HFP_RESULT_OK)
		error("hf-client: Error on AT+BCS (err=%u)", result);
}

static void bcs_cb(struct hfp_context *context, void *user_data)
{
	struct device *dev = user_data;
	unsigned int codec;
	char codecs_string[8];

	DBG("");

	if (!hfp_context_get_number(context, &codec))
		goto failed;

	if (!is_codec_supported_localy(dev, codec))
		goto failed;

	dev->negotiated_codec = codec;

	hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%u", codec);

	return;

failed:
	error("hf-client: Could not get codec");

	get_local_codecs_string(dev, codecs_string, sizeof(codecs_string));

	hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%s", codecs_string);
}

static void slc_completed(struct device *dev)
{
	int i;
	struct indicator *ag_ind;

	DBG("");

	ag_ind = dev->ag_ind;

	device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED);

	/* Notify Android with indicators */
	for (i = 0; i < HFP_INDICATOR_LAST; i++) {
		if (!ag_ind[i].cb)
			continue;

		ag_ind[i].cb(ag_ind[i].val);
	}

	/* TODO: register unsolicited results handlers */

	hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL);
	hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL);
	hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL);
	hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL);
	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
	hfp_hf_register(dev->hf, cnum_cb, "+CNUM", dev, NULL);
	hfp_hf_register(dev->hf, binp_cb, "+BINP", dev, NULL);
	hfp_hf_register(dev->hf, bcs_cb, "+BCS", dev, NULL);

	if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0"))
		info("hf-client: Could not send AT+COPS=3,0");
}

static void slc_chld_cb(struct hfp_context *context, void *user_data)
{
	struct device *dev = user_data;
	char feat[3];

	if (!hfp_context_open_container(context))
		goto failed;

	while (hfp_context_get_unquoted_string(context, feat, sizeof(feat)))
		set_chld_feat(dev, feat);

	if (!hfp_context_close_container(context))
		goto failed;

	return;

failed:
	error("hf-client: Error on CHLD response");
	slc_error(dev);
}

static void slc_chld_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	DBG("");

	hfp_hf_unregister(dev->hf, "+CHLD");

	if (result != HFP_RESULT_OK) {
		error("hf-client: CHLD error: %d", result);
		slc_error(dev);
		return;
	}

	slc_completed(dev);
}

static void slc_cmer_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	DBG("");

	if (result != HFP_RESULT_OK) {
		error("hf-client: CMER error: %d", result);
		goto failed;
	}

	/* Continue with SLC creation */
	if (!(dev->features & HFP_AG_FEAT_3WAY)) {
		slc_completed(dev);
		return;
	}

	if (!hfp_hf_register(dev->hf, slc_chld_cb, "+CHLD", dev, NULL)) {
		error("hf-client: Could not register +CHLD");
		goto failed;
	}

	if (!hfp_hf_send_command(dev->hf, slc_chld_resp, dev, "AT+CHLD=?")) {
		error("hf-client: Could not send AT+CHLD");
		goto failed;
	}

	return;

failed:
	slc_error(dev);
}

static void set_indicator_value(uint8_t index, unsigned int val,
						struct indicator *ag_ind)
{
	int i;

	for (i = 0; i < HFP_INDICATOR_LAST; i++) {
		if (index != ag_ind[i].index)
			continue;

		ag_ind[i].val = val;
		ag_ind[i].cb(val);
		return;
	}
}

static void slc_cind_status_cb(struct hfp_context *context,
							void *user_data)
{
	struct device *dev = user_data;
	uint8_t index = 1;

	DBG("");

	while (hfp_context_has_next(context)) {
		uint32_t val;

		if (!hfp_context_get_number(context, &val)) {
			error("hf-client: Error on CIND status response");
			return;
		}

		set_indicator_value(index++, val, dev->ag_ind);
	}
}

static void slc_cind_status_resp(enum hfp_result result,
							enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	DBG("");

	hfp_hf_unregister(dev->hf, "+CIND");

	if (result != HFP_RESULT_OK) {
		error("hf-client: CIND error: %d", result);
		goto failed;
	}

	/* Continue with SLC creation */
	if (!hfp_hf_send_command(dev->hf, slc_cmer_resp, dev,
							"AT+CMER=3,0,0,1")) {
		error("hf-client: Counld not send AT+CMER");
		goto failed;
	}

	return;

failed:
	slc_error(dev);
}

static void slc_cind_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	DBG("");

	hfp_hf_unregister(dev->hf, "+CIND");

	if (result != HFP_RESULT_OK) {
		error("hf-client: CIND error: %d", result);
		goto failed;
	}

	/* Continue with SLC creation */
	if (!hfp_hf_register(dev->hf, slc_cind_status_cb, "+CIND", dev,
								NULL)) {
		error("hf-client: Counld not register +CIND");
		goto failed;
	}

	if (!hfp_hf_send_command(dev->hf, slc_cind_status_resp, dev,
								"AT+CIND?")) {
		error("hf-client: Counld not send AT+CIND?");
		goto failed;
	}

	return;

failed:
	slc_error(dev);
}

static void ciev_service_cb(uint8_t val)
{
	struct hal_ev_hf_client_net_state ev;

	DBG("");

	if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) {
		error("hf-client: Incorrect state %u:", val);
		return;
	}

	ev.state = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
				HAL_EV_HF_CLIENT_NET_STATE, sizeof(ev), &ev);
}

static void ciev_call_cb(uint8_t val)
{
	struct hal_ev_hf_client_call_indicator ev;

	DBG("");

	if (val > HAL_HF_CLIENT_CALL_IND_CALL_IN_PROGERSS) {
		error("hf-client: Incorrect call state %u:", val);
		return;
	}

	ev.call = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_EV_HF_CLIENT_CALL_INDICATOR, sizeof(ev), &ev);
}

static void ciev_callsetup_cb(uint8_t val)
{
	struct hal_ev_hf_client_call_setup_indicator ev;

	DBG("");

	if (val > HAL_HF_CLIENT_CALL_SETUP_ALERTING) {
		error("hf-client: Incorrect call setup state %u:", val);
		return;
	}

	ev.call_setup = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR,
					sizeof(ev), &ev);
}

static void ciev_callheld_cb(uint8_t val)
{
	struct hal_ev_hf_client_call_held_indicator ev;

	DBG("");

	if (val > HAL_HF_CLIENT_CALL_SETUP_IND_HOLD) {
		error("hf-client: Incorrect call held state %u:", val);
		return;
	}

	ev.call_held = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR,
					sizeof(ev), &ev);
}

static void ciev_signal_cb(uint8_t val)
{
	struct hal_ev_hf_client_net_signal_strength ev;

	DBG("");

	if (val > 5) {
		error("hf-client: Incorrect signal value %u:", val);
		return;
	}

	ev.signal_strength = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH,
					sizeof(ev), &ev);
}

static void ciev_roam_cb(uint8_t val)
{
	struct hal_ev_hf_client_net_roaming_type ev;

	DBG("");

	if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) {
		error("hf-client: Incorrect roaming state %u:", val);
		return;
	}

	ev.state = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_EV_HF_CLIENT_NET_ROAMING_TYPE,
					sizeof(ev), &ev);
}

static void ciev_battchg_cb(uint8_t val)
{
	struct hal_ev_hf_client_battery_level ev;

	DBG("");

	if (val > 5) {
		error("hf-client: Incorrect battery charge value %u:", val);
		return;
	}

	ev.battery_level = val;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
			HAL_EV_HF_CLIENT_BATTERY_LEVEL, sizeof(ev), &ev);
}

static void set_indicator_parameters(uint8_t index, const char *indicator,
						unsigned int min,
						unsigned int max,
						struct indicator *ag_ind)
{
	DBG("%s, %i", indicator, index);

	/* TODO: Verify min/max values ? */

	if (strcmp("service", indicator) == 0) {
		ag_ind[HFP_INDICATOR_SERVICE].index = index;
		ag_ind[HFP_INDICATOR_SERVICE].min = min;
		ag_ind[HFP_INDICATOR_SERVICE].max = max;
		ag_ind[HFP_INDICATOR_SERVICE].cb = ciev_service_cb;
		return;
	}

	if (strcmp("call", indicator) == 0) {
		ag_ind[HFP_INDICATOR_CALL].index = index;
		ag_ind[HFP_INDICATOR_CALL].min = min;
		ag_ind[HFP_INDICATOR_CALL].max = max;
		ag_ind[HFP_INDICATOR_CALL].cb = ciev_call_cb;
		return;
	}

	if (strcmp("callsetup", indicator) == 0) {
		ag_ind[HFP_INDICATOR_CALLSETUP].index = index;
		ag_ind[HFP_INDICATOR_CALLSETUP].min = min;
		ag_ind[HFP_INDICATOR_CALLSETUP].max = max;
		ag_ind[HFP_INDICATOR_CALLSETUP].cb = ciev_callsetup_cb;
		return;
	}

	if (strcmp("callheld", indicator) == 0) {
		ag_ind[HFP_INDICATOR_CALLHELD].index = index;
		ag_ind[HFP_INDICATOR_CALLHELD].min = min;
		ag_ind[HFP_INDICATOR_CALLHELD].max = max;
		ag_ind[HFP_INDICATOR_CALLHELD].cb = ciev_callheld_cb;
		return;
	}

	if (strcmp("signal", indicator) == 0) {
		ag_ind[HFP_INDICATOR_SIGNAL].index = index;
		ag_ind[HFP_INDICATOR_SIGNAL].min = min;
		ag_ind[HFP_INDICATOR_SIGNAL].max = max;
		ag_ind[HFP_INDICATOR_SIGNAL].cb = ciev_signal_cb;
		return;
	}

	if (strcmp("roam", indicator) == 0) {
		ag_ind[HFP_INDICATOR_ROAM].index = index;
		ag_ind[HFP_INDICATOR_ROAM].min = min;
		ag_ind[HFP_INDICATOR_ROAM].max = max;
		ag_ind[HFP_INDICATOR_ROAM].cb = ciev_roam_cb;
		return;
	}

	if (strcmp("battchg", indicator) == 0) {
		ag_ind[HFP_INDICATOR_BATTCHG].index = index;
		ag_ind[HFP_INDICATOR_BATTCHG].min = min;
		ag_ind[HFP_INDICATOR_BATTCHG].max = max;
		ag_ind[HFP_INDICATOR_BATTCHG].cb = ciev_battchg_cb;
		return;
	}

	error("hf-client: Unknown indicator: %s", indicator);
}

static void slc_cind_cb(struct hfp_context *context, void *user_data)
{
	struct device *dev = user_data;
	int index = 1;

	DBG("");

	while (hfp_context_has_next(context)) {
		char name[255];
		unsigned int min, max;

		/* e.g ("callsetup",(0-3)) */
		if (!hfp_context_open_container(context))
			break;

		if (!hfp_context_get_string(context, name, sizeof(name))) {
			error("hf-client: Could not get string");
			goto failed;
		}

		if (!hfp_context_open_container(context)) {
			error("hf-client: Could not open container");
			goto failed;
		}

		if (!hfp_context_get_range(context, &min, &max)) {
			if (!hfp_context_get_number(context, &min)) {
				error("hf-client: Could not get number");
				goto failed;
			}

			if (!hfp_context_get_number(context, &max)) {
				error("hf-client: Could not get number");
				goto failed;
			}
		}

		if (!hfp_context_close_container(context)) {
			error("hf-client: Could not close container");
			goto failed;
		}

		if (!hfp_context_close_container(context)) {
			error("hf-client: Could not close container");
			goto failed;
		}

		set_indicator_parameters(index, name, min, max, dev->ag_ind);
		index++;
	}

	return;

failed:
	error("hf-client: Error on CIND response");
	slc_error(dev);
}

static void slc_bac_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	DBG("");

	if (result != HFP_RESULT_OK)
		goto failed;

	/* Continue with SLC creation */
	if (!hfp_hf_register(dev->hf, slc_cind_cb, "+CIND", dev, NULL)) {
		error("hf-client: Could not register for +CIND");
		goto failed;
	}

	if (!hfp_hf_send_command(dev->hf, slc_cind_resp, dev, "AT+CIND=?"))
		goto failed;

	return;

failed:
	error("hf-client: Error on BAC response");
	slc_error(dev);
}

static bool send_supported_codecs(struct device *dev)
{
	char codecs_string[8];
	char bac[16];

	memset(bac, 0, sizeof(bac));

	strcpy(bac, "AT+BAC=");

	get_local_codecs_string(dev, codecs_string, sizeof(codecs_string));
	strcat(bac, codecs_string);

	return hfp_hf_send_command(dev->hf, slc_bac_resp, dev, bac);
}

static void slc_brsf_cb(struct hfp_context *context, void *user_data)
{
	unsigned int feat;
	struct device *dev = user_data;

	DBG("");

	if (hfp_context_get_number(context, &feat))
		dev->features = feat;
}

static void slc_brsf_resp(enum hfp_result result, enum hfp_error cme_err,
							void *user_data)
{
	struct device *dev = user_data;

	hfp_hf_unregister(dev->hf, "+BRSF");

	if (result != HFP_RESULT_OK) {
		error("hf-client: BRSF error: %d", result);
		goto failed;
	}

	/* Continue with SLC creation */
	if (codec_negotiation_supported(dev)) {
		if (send_supported_codecs(dev))
			return;

		error("hf-client: Could not send BAC command");
		goto failed;
	}

	/* No WBS on remote side. Continue with indicators */
	if (!hfp_hf_register(dev->hf, slc_cind_cb, "+CIND", dev, NULL)) {
		error("hf-client: Could not register for +CIND");
		goto failed;
	}

	if (!hfp_hf_send_command(dev->hf, slc_cind_resp, dev, "AT+CIND=?")) {
		error("hf-client: Could not send AT+CIND command");
		goto failed;
	}

	return;

failed:
	slc_error(dev);
}

static bool create_slc(struct device *dev)
{
	DBG("");

	if (!hfp_hf_register(dev->hf, slc_brsf_cb, "+BRSF", dev, NULL))
		return false;

	return hfp_hf_send_command(dev->hf, slc_brsf_resp, dev, "AT+BRSF=%u",
							hfp_hf_features);
}

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

	DBG("");

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

	dev->hf = hfp_hf_new(g_io_channel_unix_get_fd(chan));
	if (!dev->hf) {
		error("hf-client: Could not create hfp io");
		goto failed;
	}

	g_io_channel_set_close_on_unref(chan, FALSE);

	hfp_hf_set_close_on_unref(dev->hf, true);
	hfp_hf_set_disconnect_handler(dev->hf, disconnect_watch, dev, NULL);

	if (!create_slc(dev)) {
		error("hf-client: Could not start SLC creation");
		hfp_hf_disconnect(dev->hf);
		goto failed;
	}

	return;

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

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

	DBG("");

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

	if (!recs || !recs->data) {
		info("hf-client: no HFP SDP records found");
		goto failed;
	}

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

	/* 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_AGW_SVCLASS_ID) {
		error("hf-client: invalid service record or not HFP");
		goto failed;
	}

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

	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("hf-client: unable to get RFCOMM channel from record");
		goto failed;
	}

	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("hf-client: unable to connect: %s", gerr->message);
		g_error_free(gerr);
		goto failed;
	}

	g_io_channel_unref(io);
	return;

failed:
	device_destroy(dev);
}

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

	sdp_uuid16_create(&uuid, HANDSFREE_AGW_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)
{
	struct device *dev;
	const struct hal_cmd_hf_client_connect *cmd = buf;
	uint32_t status;
	bdaddr_t bdaddr;
	char addr[18];

	DBG("");

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

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

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

	if (dev->state != HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) {
		status = HAL_STATUS_FAILED;
		goto done;
	}

	if (sdp_search_hfp(dev) < 0) {
		status = HAL_STATUS_FAILED;
		device_destroy(dev);
		goto done;
	}

	device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

done:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
					HAL_OP_HF_CLIENT_CONNECT, status);
}

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

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

	DBG("Incoming connection from %s", address);

	dev = get_device(&bdaddr);
	if (!dev) {
		error("hf-client: There is other AG connected");
		goto drop;
	}

	if (dev->state != HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) {
		/* TODO: Handle colision */
		error("hf-client: Connections is up or ongoing ?");
		goto drop;
	}

	device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_CONNECTING);

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

	return;

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

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_HF_CLIENT_CONNECT */
	{ handle_connect, false,
				sizeof(struct hal_cmd_hf_client_connect) },
	/* HAL_OP_HF_CLIENT_DISCONNECT */
	{ handle_disconnect, false,
				sizeof(struct hal_cmd_hf_client_disconnect) },
	/* HAL_OP_HF_CLIENT_CONNECT_AUDIO */
	{ handle_connect_audio, false,
			sizeof(struct hal_cmd_hf_client_connect_audio) },
	/* HAL_OP_HF_CLIENT_DISCONNECT_AUDIO */
	{ handle_disconnect_audio, false,
			sizeof(struct hal_cmd_hf_client_disconnect_audio) },
	/* define HAL_OP_HF_CLIENT_START_VR */
	{ handle_start_vr, false, 0 },
	/* define HAL_OP_HF_CLIENT_STOP_VR */
	{ handle_stop_vr, false, 0 },
	/* HAL_OP_HF_CLIENT_VOLUME_CONTROL */
	{ handle_volume_control, false,
			sizeof(struct hal_cmd_hf_client_volume_control) },
	/* HAL_OP_HF_CLIENT_DIAL */
	{ handle_dial, true, sizeof(struct hal_cmd_hf_client_dial) },
	/* HAL_OP_HF_CLIENT_DIAL_MEMORY */
	{ handle_dial_memory, false,
				sizeof(struct hal_cmd_hf_client_dial_memory) },
	/* HAL_OP_HF_CLIENT_CALL_ACTION */
	{ handle_call_action, false,
				sizeof(struct hal_cmd_hf_client_call_action) },
	/* HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS */
	{ handle_query_current_calls, false, 0 },
	/* HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME */
	{ handle_query_operator_name, false, 0 },
	/* HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO */
	{ handle_retrieve_subscr_info, false, 0 },
	/* HAL_OP_HF_CLIENT_SEND_DTMF */
	{ handle_send_dtmf, false,
				sizeof(struct hal_cmd_hf_client_send_dtmf) },
	/* HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM */
	{ handle_get_last_vc_tag_num, false, 0 },
};

static sdp_record_t *hfp_hf_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;
	uint16_t sdpfeat;
	uint8_t ch = HFP_HF_CHANNEL;

	record = sdp_record_alloc();
	if (!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_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_hf_features & 0x0000003F;
	if (hfp_hf_features & HFP_HF_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 unit", NULL, NULL);

	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_hf_client(void)
{
	sdp_record_t *rec;
	GError *err = NULL;

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

	hfp_hf_features = HFP_HF_FEATURES;

	rec = hfp_hf_record();
	if (!rec) {
		error("hf-client: Could not create service record");
		goto failed;
	}

	if (bt_adapter_add_record(rec, 0) < 0) {
		error("hf-client: Failed to register service record");
		sdp_record_free(rec);
		goto failed;
	}

	hfp_hf_record_id = rec->handle;

	return true;

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

	return false;
}

static void cleanup_hfp_hf(void)
{
	if (hfp_hf_server) {
		g_io_channel_shutdown(hfp_hf_server, TRUE, NULL);
		g_io_channel_unref(hfp_hf_server);
		hfp_hf_server = NULL;
	}

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

	if (sco) {
		bt_sco_unref(sco);
		sco = NULL;
	}
}

static bool confirm_sco_cb(const bdaddr_t *addr, uint16_t *voice_settings)
{
	struct device *dev;

	DBG("");

	dev = find_device(addr);
	if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED) {
		error("hf-client: No device or SLC not ready");
		return false;
	}

	set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING);

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

	return true;
}

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

	DBG("SCO Status %u", status);

	/* Device shall be there, just sanity check */
	dev = find_device(addr);
	if (!dev) {
		error("hf-client: There is no device?");
		return;
	}

	if (status != SCO_STATUS_OK) {
		audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED;
		goto done;
	}

	if (dev->negotiated_codec == CODEC_ID_MSBC)
		audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC;
	else
		audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED;

done:
	set_audio_state(dev, audio_state);
}

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

	DBG("");

	dev = find_device(addr);
	if (!dev) {
		error("hf-client: No device");
		return;
	}

	set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED);
}

bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
{
	DBG("");

	devices = queue_new();
	if (!devices) {
		error("hf-client: Could not create devices list");
		goto failed;
	}

	bacpy(&adapter_addr, addr);

	if (!enable_hf_client())
		goto failed;

	sco = bt_sco_new(addr);
	if (!sco) {
		error("hf-client: Cannot create SCO. HFP AG is in use ?");
		goto failed;
	}

	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);

	hal_ipc = ipc;
	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;

failed:
	cleanup_hfp_hf();
	queue_destroy(devices, free);
	devices = NULL;

	return false;
}

void bt_hf_client_unregister(void)
{
	DBG("");

	cleanup_hfp_hf();

	queue_destroy(devices, (void *) device_destroy);
	devices = NULL;

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