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

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

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus.h>

#include "log.h"
#include "telephony.h"

enum net_registration_status {
	NETWORK_REG_STATUS_HOME = 0x00,
	NETWORK_REG_STATUS_ROAM,
	NETWORK_REG_STATUS_NOSERV
};

struct voice_call {
	char *obj_path;
	int status;
	gboolean originating;
	gboolean conference;
	char *number;
	guint watch;
};

static DBusConnection *connection = NULL;
static char *modem_obj_path = NULL;
static char *last_dialed_number = NULL;
static GSList *calls = NULL;
static GSList *watches = NULL;
static GSList *pending = NULL;

#define OFONO_BUS_NAME "org.ofono"
#define OFONO_PATH "/"
#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"

/* HAL battery namespace key values */
static int battchg_cur = -1;    /* "battery.charge_level.current" */
static int battchg_last = -1;   /* "battery.charge_level.last_full" */
static int battchg_design = -1; /* "battery.charge_level.design" */

static struct {
	uint8_t status;
	uint32_t signals_bar;
	char *operator_name;
} net = {
	.status = NETWORK_REG_STATUS_NOSERV,
	.signals_bar = 0,
	.operator_name = NULL,
};

static const char *chld_str = "0,1,1x,2,2x,3,4";
static char *subscriber_number = NULL;

static gboolean events_enabled = FALSE;

static struct indicator ofono_indicators[] =
{
	{ "battchg",	"0-5",	5,	TRUE },
	{ "signal",	"0-5",	5,	TRUE },
	{ "service",	"0,1",	1,	TRUE },
	{ "call",	"0,1",	0,	TRUE },
	{ "callsetup",	"0-3",	0,	TRUE },
	{ "callheld",	"0-2",	0,	FALSE },
	{ "roam",	"0,1",	0,	TRUE },
	{ NULL }
};

static struct voice_call *find_vc(const char *path)
{
	GSList *l;

	for (l = calls; l != NULL; l = l->next) {
		struct voice_call *vc = l->data;

		if (g_str_equal(vc->obj_path, path))
			return vc;
	}

	return NULL;
}

static struct voice_call *find_vc_with_status(int status)
{
	GSList *l;

	for (l = calls; l != NULL; l = l->next) {
		struct voice_call *vc = l->data;

		if (vc->status == status)
			return vc;
	}

	return NULL;
}

static struct voice_call *find_vc_without_status(int status)
{
	GSList *l;

	for (l = calls; l != NULL; l = l->next) {
		struct voice_call *call = l->data;

		if (call->status != status)
			return call;
	}

	return NULL;
}

static int number_type(const char *number)
{
	if (number == NULL)
		return NUMBER_TYPE_TELEPHONY;

	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
		return NUMBER_TYPE_INTERNATIONAL;

	return NUMBER_TYPE_TELEPHONY;
}

void telephony_device_connected(void *telephony_device)
{
	struct voice_call *coming;

	DBG("telephony-ofono: device %p connected", telephony_device);

	coming = find_vc_with_status(CALL_STATUS_ALERTING);
	if (coming) {
		if (find_vc_with_status(CALL_STATUS_ACTIVE))
			telephony_call_waiting_ind(coming->number,
						number_type(coming->number));
		else
			telephony_incoming_call_ind(coming->number,
						number_type(coming->number));
	}
}

void telephony_device_disconnected(void *telephony_device)
{
	DBG("telephony-ofono: device %p disconnected", telephony_device);
	events_enabled = FALSE;
}

void telephony_event_reporting_req(void *telephony_device, int ind)
{
	events_enabled = ind == 1 ? TRUE : FALSE;

	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_response_and_hold_req(void *telephony_device, int rh)
{
	telephony_response_and_hold_rsp(telephony_device,
						CME_ERROR_NOT_SUPPORTED);
}

void telephony_last_dialed_number_req(void *telephony_device)
{
	DBG("telephony-ofono: last dialed number request");

	if (last_dialed_number)
		telephony_dial_number_req(telephony_device, last_dialed_number);
	else
		telephony_last_dialed_number_rsp(telephony_device,
				CME_ERROR_NOT_ALLOWED);
}

static int send_method_call(const char *dest, const char *path,
                                const char *interface, const char *method,
                                DBusPendingCallNotifyFunction cb,
                                void *user_data, int type, ...)
{
	DBusMessage *msg;
	DBusPendingCall *call;
	va_list args;

	msg = dbus_message_new_method_call(dest, path, interface, method);
	if (!msg) {
		error("Unable to allocate new D-Bus %s message", method);
		return -ENOMEM;
	}

	va_start(args, type);

	if (!dbus_message_append_args_valist(msg, type, args)) {
		dbus_message_unref(msg);
		va_end(args);
		return -EIO;
	}

	va_end(args);

	if (!cb) {
		g_dbus_send_message(connection, msg);
		return 0;
	}

	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
		error("Sending %s failed", method);
		dbus_message_unref(msg);
		return -EIO;
	}

	dbus_pending_call_set_notify(call, cb, user_data, NULL);
	pending = g_slist_prepend(pending, call);
	dbus_message_unref(msg);

	return 0;
}

static int answer_call(struct voice_call *vc)
{
	DBG("%s", vc->number);
	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
						OFONO_VC_INTERFACE, "Answer",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int release_call(struct voice_call *vc)
{
	DBG("%s", vc->number);
	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
						OFONO_VC_INTERFACE, "Hangup",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int release_answer_calls()
{
	DBG("");
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"ReleaseAndAnswer",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int split_call(struct voice_call *call)
{
	DBG("%s", call->number);
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"PrivateChat",
						NULL, NULL,
						DBUS_TYPE_OBJECT_PATH,
						call->obj_path,
						DBUS_TYPE_INVALID);
	return -1;
}

static int swap_calls(void)
{
	DBG("");
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"SwapCalls",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int create_conference(void)
{
	DBG("");
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"CreateMultiparty",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int release_conference(void)
{
	DBG("");
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"HangupMultiparty",
						NULL, NULL, DBUS_TYPE_INVALID);
}

static int call_transfer(void)
{
	DBG("");
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
						OFONO_VCMANAGER_INTERFACE,
						"Transfer",
						NULL, NULL, DBUS_TYPE_INVALID);
}

void telephony_terminate_call_req(void *telephony_device)
{
	struct voice_call *call;
	struct voice_call *alerting;
	int err;

	call = find_vc_with_status(CALL_STATUS_ACTIVE);
	if (!call)
		call = calls->data;

	if (!call) {
		error("No active call");
		telephony_terminate_call_rsp(telephony_device,
						CME_ERROR_NOT_ALLOWED);
		return;
	}

	alerting = find_vc_with_status(CALL_STATUS_ALERTING);
	if (call->status == CALL_STATUS_HELD && alerting)
		err = release_call(alerting);
	else if (call->conference)
		err = release_conference();
	else
		err = release_call(call);

	if (err < 0)
		telephony_terminate_call_rsp(telephony_device,
						CME_ERROR_AG_FAILURE);
	else
		telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_answer_call_req(void *telephony_device)
{
	struct voice_call *vc;
	int ret;

	vc = find_vc_with_status(CALL_STATUS_INCOMING);
	if (!vc)
		vc = find_vc_with_status(CALL_STATUS_ALERTING);

	if (!vc)
		vc = find_vc_with_status(CALL_STATUS_WAITING);

	if (!vc) {
		telephony_answer_call_rsp(telephony_device,
					CME_ERROR_NOT_ALLOWED);
		return;
	}

	ret = answer_call(vc);
	if (ret < 0) {
		telephony_answer_call_rsp(telephony_device,
					CME_ERROR_AG_FAILURE);
		return;
	}

	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_dial_number_req(void *telephony_device, const char *number)
{
	const char *clir;
	int ret;

	DBG("telephony-ofono: dial request to %s", number);

	if (!modem_obj_path) {
		telephony_dial_number_rsp(telephony_device,
					CME_ERROR_AG_FAILURE);
		return;
	}

	if (!strncmp(number, "*31#", 4)) {
		number += 4;
		clir = "enabled";
	} else if (!strncmp(number, "#31#", 4)) {
		number += 4;
		clir =  "disabled";
	} else
		clir = "default";

	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
			OFONO_VCMANAGER_INTERFACE,
                        "Dial", NULL, NULL,
			DBUS_TYPE_STRING, &number,
			DBUS_TYPE_STRING, &clir,
			DBUS_TYPE_INVALID);

	if (ret < 0)
		telephony_dial_number_rsp(telephony_device,
			CME_ERROR_AG_FAILURE);
	else
		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_transmit_dtmf_req(void *telephony_device, char tone)
{
	char *tone_string;
	int ret;

	DBG("telephony-ofono: transmit dtmf: %c", tone);

	if (!modem_obj_path) {
		telephony_transmit_dtmf_rsp(telephony_device,
					CME_ERROR_AG_FAILURE);
		return;
	}

	tone_string = g_strdup_printf("%c", tone);
	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
			OFONO_VCMANAGER_INTERFACE,
			"SendTones", NULL, NULL,
			DBUS_TYPE_STRING, &tone_string,
			DBUS_TYPE_INVALID);
	g_free(tone_string);

	if (ret < 0)
		telephony_transmit_dtmf_rsp(telephony_device,
			CME_ERROR_AG_FAILURE);
	else
		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_subscriber_number_req(void *telephony_device)
{
	DBG("telephony-ofono: subscriber number request");

	if (subscriber_number)
		telephony_subscriber_number_ind(subscriber_number,
						NUMBER_TYPE_TELEPHONY,
						SUBSCRIBER_SERVICE_VOICE);
	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_list_current_calls_req(void *telephony_device)
{
	GSList *l;
	int i;

	DBG("telephony-ofono: list current calls request");

	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
		struct voice_call *vc = l->data;
		int direction, multiparty;

		direction = vc->originating ?
				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;

		multiparty = vc->conference ?
				CALL_MULTIPARTY_YES : CALL_MULTIPARTY_NO;

		DBG("call %s direction %d multiparty %d", vc->number,
							direction, multiparty);

		telephony_list_current_call_ind(i, direction, vc->status,
					CALL_MODE_VOICE, multiparty,
					vc->number, number_type(vc->number));
	}

	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_operator_selection_req(void *telephony_device)
{
	DBG("telephony-ofono: operator selection request");

	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
				net.operator_name ? net.operator_name : "");
	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
}

static void foreach_vc_with_status(int status,
					int (*func)(struct voice_call *vc))
{
	GSList *l;

	for (l = calls; l != NULL; l = l->next) {
		struct voice_call *call = l->data;

		if (call->status == status)
			func(call);
	}
}

void telephony_call_hold_req(void *telephony_device, const char *cmd)
{
	const char *idx;
	struct voice_call *call;
	int err = 0;

	DBG("telephony-ofono: got call hold request %s", cmd);

	if (strlen(cmd) > 1)
		idx = &cmd[1];
	else
		idx = NULL;

	if (idx)
		call = g_slist_nth_data(calls, strtol(idx, NULL, 0) - 1);
	else
		call = NULL;

	switch (cmd[0]) {
	case '0':
		if (find_vc_with_status(CALL_STATUS_WAITING))
			foreach_vc_with_status(CALL_STATUS_WAITING,
								release_call);
		else
			foreach_vc_with_status(CALL_STATUS_HELD, release_call);
		break;
	case '1':
		if (idx) {
			if (call)
				err = release_call(call);
			break;
		}
		err = release_answer_calls();
		break;
	case '2':
		if (idx) {
			if (call)
				err = split_call(call);
		} else {
			call = find_vc_with_status(CALL_STATUS_WAITING);

			if (call)
				err = answer_call(call);
			else
				err = swap_calls();
		}
		break;
	case '3':
		if (find_vc_with_status(CALL_STATUS_HELD) ||
				find_vc_with_status(CALL_STATUS_WAITING))
			err = create_conference();
		break;
	case '4':
		err = call_transfer();
		break;
	default:
		DBG("Unknown call hold request");
		break;
	}

	if (err)
		telephony_call_hold_rsp(telephony_device,
					CME_ERROR_AG_FAILURE);
	else
		telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
{
	DBG("telephony-ofono: got %s NR and EC request",
			enable ? "enable" : "disable");

	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_key_press_req(void *telephony_device, const char *keys)
{
	struct voice_call *active, *incoming;
	int err;

	DBG("telephony-ofono: got key press request for %s", keys);

	incoming = find_vc_with_status(CALL_STATUS_INCOMING);

	active = find_vc_with_status(CALL_STATUS_ACTIVE);

	if (incoming)
		err = answer_call(incoming);
	else if (active)
		err = release_call(active);
	else
		err = 0;

	if (err < 0)
		telephony_key_press_rsp(telephony_device,
							CME_ERROR_AG_FAILURE);
	else
		telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_voice_dial_req(void *telephony_device, gboolean enable)
{
	DBG("telephony-ofono: got %s voice dial request",
			enable ? "enable" : "disable");

	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
}

static gboolean iter_get_basic_args(DBusMessageIter *iter,
					int first_arg_type, ...)
{
	int type;
	va_list ap;

	va_start(ap, first_arg_type);

	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
		type = va_arg(ap, int)) {
		void *value = va_arg(ap, void *);
		int real_type = dbus_message_iter_get_arg_type(iter);

		if (real_type != type) {
			error("iter_get_basic_args: expected %c but got %c",
				(char) type, (char) real_type);
			break;
		}

		dbus_message_iter_get_basic(iter, value);
		dbus_message_iter_next(iter);
	}

	va_end(ap);

	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
}

static void call_free(struct voice_call *vc)
{
	DBG("%s", vc->obj_path);

	if (vc->status == CALL_STATUS_ACTIVE)
		telephony_update_indicator(ofono_indicators, "call",
							EV_CALL_INACTIVE);
	else
		telephony_update_indicator(ofono_indicators, "callsetup",
							EV_CALLSETUP_INACTIVE);

	if (vc->status == CALL_STATUS_INCOMING)
		telephony_calling_stopped_ind();

	g_dbus_remove_watch(connection, vc->watch);
	g_free(vc->obj_path);
	g_free(vc->number);
	g_free(vc);
}

static gboolean handle_vc_property_changed(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct voice_call *vc = data;
	const char *obj_path = dbus_message_get_path(msg);
	DBusMessageIter iter, sub;
	const char *property, *state;

	DBG("path %s", obj_path);

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
		error("Unexpected signature in vc PropertyChanged signal");
		return TRUE;
	}

	dbus_message_iter_get_basic(&iter, &property);
	DBG("property %s", property);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &sub);
	if (g_str_equal(property, "State")) {
		dbus_message_iter_get_basic(&sub, &state);
		DBG("State %s", state);
		if (g_str_equal(state, "disconnected")) {
			calls = g_slist_remove(calls, vc);
			call_free(vc);
		} else if (g_str_equal(state, "active")) {
			telephony_update_indicator(ofono_indicators,
							"call", EV_CALL_ACTIVE);
			telephony_update_indicator(ofono_indicators,
							"callsetup",
							EV_CALLSETUP_INACTIVE);
			if (vc->status == CALL_STATUS_INCOMING)
				telephony_calling_stopped_ind();
			vc->status = CALL_STATUS_ACTIVE;
		} else if (g_str_equal(state, "alerting")) {
			telephony_update_indicator(ofono_indicators,
					"callsetup", EV_CALLSETUP_ALERTING);
			vc->status = CALL_STATUS_ALERTING;
			vc->originating = TRUE;
		} else if (g_str_equal(state, "incoming")) {
			/* state change from waiting to incoming */
			telephony_update_indicator(ofono_indicators,
					"callsetup", EV_CALLSETUP_INCOMING);
			telephony_incoming_call_ind(vc->number,
						NUMBER_TYPE_TELEPHONY);
			vc->status = CALL_STATUS_INCOMING;
			vc->originating = FALSE;
		} else if (g_str_equal(state, "held")) {
			vc->status = CALL_STATUS_HELD;
			if (find_vc_without_status(CALL_STATUS_HELD))
				telephony_update_indicator(ofono_indicators,
							"callheld",
							EV_CALLHELD_MULTIPLE);
			else
				telephony_update_indicator(ofono_indicators,
							"callheld",
							EV_CALLHELD_ON_HOLD);
		}
	} else if (g_str_equal(property, "Multiparty")) {
		dbus_bool_t multiparty;

		dbus_message_iter_get_basic(&sub, &multiparty);
		DBG("Multiparty %s", multiparty ? "True" : "False");
		vc->conference = multiparty;
	}

	return TRUE;
}

static struct voice_call *call_new(const char *path, DBusMessageIter *properties)
{
	struct voice_call *vc;

	DBG("%s", path);

	vc = g_new0(struct voice_call, 1);
	vc->obj_path = g_strdup(path);
	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
					OFONO_VC_INTERFACE, "PropertyChanged",
					handle_vc_property_changed, vc, NULL);

	while (dbus_message_iter_get_arg_type(properties)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		const char *property, *cli, *state;
		dbus_bool_t multiparty;

		dbus_message_iter_recurse(properties, &entry);
		dbus_message_iter_get_basic(&entry, &property);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (g_str_equal(property, "LineIdentification")) {
			dbus_message_iter_get_basic(&value, &cli);
			DBG("cli %s", cli);
			vc->number = g_strdup(cli);
		} else if (g_str_equal(property, "State")) {
			dbus_message_iter_get_basic(&value, &state);
			DBG("state %s", state);
			if (g_str_equal(state, "incoming"))
				vc->status = CALL_STATUS_INCOMING;
			else if (g_str_equal(state, "dialing"))
				vc->status = CALL_STATUS_DIALING;
			else if (g_str_equal(state, "alerting"))
				vc->status = CALL_STATUS_ALERTING;
			else if (g_str_equal(state, "waiting"))
				vc->status = CALL_STATUS_WAITING;
			else if (g_str_equal(state, "held"))
				vc->status = CALL_STATUS_HELD;
		} else if (g_str_equal(property, "Multiparty")) {
			dbus_message_iter_get_basic(&value, &multiparty);
			DBG("Multipary %s", multiparty ? "True" : "False");
			vc->conference = multiparty;
		}

		dbus_message_iter_next(properties);
	}

	switch (vc->status) {
	case CALL_STATUS_INCOMING:
		DBG("CALL_STATUS_INCOMING");
		vc->originating = FALSE;
		telephony_update_indicator(ofono_indicators, "callsetup",
					EV_CALLSETUP_INCOMING);
		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
		break;
	case CALL_STATUS_DIALING:
		DBG("CALL_STATUS_DIALING");
		vc->originating = TRUE;
		g_free(last_dialed_number);
		last_dialed_number = g_strdup(vc->number);
		telephony_update_indicator(ofono_indicators, "callsetup",
					EV_CALLSETUP_OUTGOING);
		break;
	case CALL_STATUS_ALERTING:
		DBG("CALL_STATUS_ALERTING");
		vc->originating = TRUE;
		g_free(last_dialed_number);
		last_dialed_number = g_strdup(vc->number);
		telephony_update_indicator(ofono_indicators, "callsetup",
					EV_CALLSETUP_ALERTING);
		break;
	case CALL_STATUS_WAITING:
		DBG("CALL_STATUS_WAITING");
		vc->originating = FALSE;
		telephony_update_indicator(ofono_indicators, "callsetup",
					EV_CALLSETUP_INCOMING);
		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
		break;
	}

	return vc;
}

static void remove_pending(DBusPendingCall *call)
{
	pending = g_slist_remove(pending, call);
	dbus_pending_call_unref(call);
}

static void call_added(const char *path, DBusMessageIter *properties)
{
	struct voice_call *vc;

	DBG("%s", path);

	vc = find_vc(path);
	if (vc)
		return;

	vc = call_new(path, properties);
	calls = g_slist_prepend(calls, vc);
}

static void get_calls_reply(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	DBusMessageIter iter, entry;

	DBG("");
	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		error("ofono replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	dbus_message_iter_init(reply, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &entry);

	while (dbus_message_iter_get_arg_type(&entry)
						== DBUS_TYPE_STRUCT) {
		const char *path;
		DBusMessageIter value, properties;

		dbus_message_iter_recurse(&entry, &value);
		dbus_message_iter_get_basic(&value, &path);

		dbus_message_iter_next(&value);
		dbus_message_iter_recurse(&value, &properties);

		call_added(path, &properties);

		dbus_message_iter_next(&entry);
	}

done:
	dbus_message_unref(reply);
	remove_pending(call);
}

static void handle_network_property(const char *property, DBusMessageIter *variant)
{
	const char *status, *operator;
	unsigned int signals_bar;

	if (g_str_equal(property, "Status")) {
		dbus_message_iter_get_basic(variant, &status);
		DBG("Status is %s", status);
		if (g_str_equal(status, "registered")) {
			net.status = NETWORK_REG_STATUS_HOME;
			telephony_update_indicator(ofono_indicators,
						"roam", EV_ROAM_INACTIVE);
			telephony_update_indicator(ofono_indicators,
						"service", EV_SERVICE_PRESENT);
		} else if (g_str_equal(status, "roaming")) {
			net.status = NETWORK_REG_STATUS_ROAM;
			telephony_update_indicator(ofono_indicators,
						"roam", EV_ROAM_ACTIVE);
			telephony_update_indicator(ofono_indicators,
						"service", EV_SERVICE_PRESENT);
		} else {
			net.status = NETWORK_REG_STATUS_NOSERV;
			telephony_update_indicator(ofono_indicators,
						"roam", EV_ROAM_INACTIVE);
			telephony_update_indicator(ofono_indicators,
						"service", EV_SERVICE_NONE);
		}
	} else if (g_str_equal(property, "Name")) {
		dbus_message_iter_get_basic(variant, &operator);
		DBG("Operator is %s", operator);
		g_free(net.operator_name);
		net.operator_name = g_strdup(operator);
	} else if (g_str_equal(property, "SignalStrength")) {
		dbus_message_iter_get_basic(variant, &signals_bar);
		DBG("SignalStrength is %d", signals_bar);
		net.signals_bar = signals_bar;
		telephony_update_indicator(ofono_indicators, "signal",
						(signals_bar + 20) / 21);
	}
}

static int parse_network_properties(DBusMessageIter *properties)
{
	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
				AG_FEATURE_INBAND_RINGTONE |
				AG_FEATURE_REJECT_A_CALL |
				AG_FEATURE_ENHANCED_CALL_STATUS |
				AG_FEATURE_ENHANCED_CALL_CONTROL |
				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
				AG_FEATURE_THREE_WAY_CALLING;
	int i;

	/* Reset indicators */
	for (i = 0; ofono_indicators[i].desc != NULL; i++) {
		if (g_str_equal(ofono_indicators[i].desc, "battchg"))
			ofono_indicators[i].val = 5;
		else
			ofono_indicators[i].val = 0;
	}

	while (dbus_message_iter_get_arg_type(properties)
						== DBUS_TYPE_DICT_ENTRY) {
		const char *key;
		DBusMessageIter value, entry;

		dbus_message_iter_recurse(properties, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		handle_network_property(key, &value);

		dbus_message_iter_next(properties);
	}

	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
								chld_str);

	return 0;
}

static void get_properties_reply(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	DBusMessageIter iter, properties;
	int ret = 0;

	DBG("");
	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		error("ofono replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	dbus_message_iter_init(reply, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &properties);

	ret = parse_network_properties(&properties);
	if (ret < 0) {
		error("Unable to parse %s.GetProperty reply",
						OFONO_NETWORKREG_INTERFACE);
		goto done;
	}

	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
				OFONO_VCMANAGER_INTERFACE, "GetCalls",
				get_calls_reply, NULL, DBUS_TYPE_INVALID);
	if (ret < 0)
		error("Unable to send %s.GetCalls",
						OFONO_VCMANAGER_INTERFACE);

done:
	dbus_message_unref(reply);
	remove_pending(call);
}

static void network_found(const char *path)
{
	int ret;

	DBG("%s", path);

	modem_obj_path = g_strdup(path);

	ret = send_method_call(OFONO_BUS_NAME, path,
				OFONO_NETWORKREG_INTERFACE, "GetProperties",
				get_properties_reply, NULL, DBUS_TYPE_INVALID);
	if (ret < 0)
		error("Unable to send %s.GetProperties",
						OFONO_NETWORKREG_INTERFACE);
}

static void modem_removed(const char *path)
{
	if (g_strcmp0(modem_obj_path, path) != 0)
		return;

	DBG("%s", path);

	g_slist_foreach(calls, (GFunc) call_free, NULL);
	g_slist_free(calls);
	calls = NULL;

	g_free(net.operator_name);
	net.operator_name = NULL;
	net.status = NETWORK_REG_STATUS_NOSERV;
	net.signals_bar = 0;

	g_free(modem_obj_path);
	modem_obj_path = NULL;
}

static void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
{
	DBG("%s", path);

	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
		const char *iface;

		dbus_message_iter_get_basic(ifaces, &iface);

		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
			network_found(path);
			return;
		}

		dbus_message_iter_next(ifaces);
	}

	modem_removed(path);
}

static void modem_added(const char *path, DBusMessageIter *properties)
{
	if (modem_obj_path != NULL) {
		DBG("Ignoring, modem already exist");
		return;
	}

	DBG("%s", path);

	while (dbus_message_iter_get_arg_type(properties)
						== DBUS_TYPE_DICT_ENTRY) {
		const char *key;
		DBusMessageIter interfaces, value, entry;

		dbus_message_iter_recurse(properties, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (strcasecmp(key, "Interfaces") != 0)
			goto next;

		if (dbus_message_iter_get_arg_type(&value)
							!= DBUS_TYPE_ARRAY) {
			error("Invalid Signature");
			return;
		}

		dbus_message_iter_recurse(&value, &interfaces);

		parse_modem_interfaces(path, &interfaces);

		if (modem_obj_path != NULL)
			return;

	next:
		dbus_message_iter_next(properties);
	}
}

static void get_modems_reply(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	DBusMessageIter iter, entry;

	DBG("");
	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		error("ofono replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	/* Skip modem selection if a modem already exist */
	if (modem_obj_path != NULL)
		goto done;

	dbus_message_iter_init(reply, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &entry);

	while (dbus_message_iter_get_arg_type(&entry)
						== DBUS_TYPE_STRUCT) {
		const char *path;
		DBusMessageIter item, properties;

		dbus_message_iter_recurse(&entry, &item);
		dbus_message_iter_get_basic(&item, &path);

		dbus_message_iter_next(&item);
		dbus_message_iter_recurse(&item, &properties);

		modem_added(path, &properties);
		if (modem_obj_path != NULL)
			break;

		dbus_message_iter_next(&entry);
	}

done:
	dbus_message_unref(reply);
	remove_pending(call);
}

static gboolean handle_network_property_changed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, variant;
	const char *property;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
		error("Unexpected signature in networkregistration"
					" PropertyChanged signal");
		return TRUE;
	}
	dbus_message_iter_get_basic(&iter, &property);
	DBG("in handle_registration_property_changed(),"
					" the property is %s", property);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &variant);

	handle_network_property(property, &variant);

	return TRUE;
}

static void handle_modem_property(const char *path, const char *property,
						DBusMessageIter *variant)
{
	DBG("%s", property);

	if (g_str_equal(property, "Interfaces")) {
		DBusMessageIter interfaces;

		if (dbus_message_iter_get_arg_type(variant)
							!= DBUS_TYPE_ARRAY) {
			error("Invalid signature");
			return;
		}

		dbus_message_iter_recurse(variant, &interfaces);
		parse_modem_interfaces(path, &interfaces);
	}
}

static gboolean handle_modem_property_changed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, variant;
	const char *property, *path;

	path = dbus_message_get_path(msg);

	/* Ignore if modem already exist and paths doesn't match */
	if (modem_obj_path != NULL &&
				g_str_equal(path, modem_obj_path) == FALSE)
		return TRUE;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
		error("Unexpected signature in %s.%s PropertyChanged signal",
					dbus_message_get_interface(msg),
					dbus_message_get_member(msg));
		return TRUE;
	}

	dbus_message_iter_get_basic(&iter, &property);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &variant);

	handle_modem_property(path, property, &variant);

	return TRUE;
}

static gboolean handle_vcmanager_call_added(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, properties;
	const char *path = dbus_message_get_path(msg);

	/* Ignore call if modem path doesn't math */
	if (g_strcmp0(modem_obj_path, path) != 0)
		return TRUE;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter)
						!= DBUS_TYPE_OBJECT_PATH) {
		error("Unexpected signature in %s.%s signal",
					dbus_message_get_interface(msg),
					dbus_message_get_member(msg));
		return TRUE;
	}

	dbus_message_iter_get_basic(&iter, &path);
	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &properties);

	call_added(path, &properties);

	return TRUE;
}

static void call_removed(const char *path)
{
	struct voice_call *vc;

	DBG("%s", path);

	vc = find_vc(path);
	if (vc == NULL)
		return;

	calls = g_slist_remove(calls, vc);
	call_free(vc);
}

static gboolean handle_vcmanager_call_removed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *path = dbus_message_get_path(msg);

	/* Ignore call if modem path doesn't math */
	if (g_strcmp0(modem_obj_path, path) != 0)
		return TRUE;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_OBJECT_PATH, &path,
				DBUS_TYPE_INVALID)) {
		error("Unexpected signature in %s.%s signal",
					dbus_message_get_interface(msg),
					dbus_message_get_member(msg));
		return TRUE;
	}

	call_removed(path);

	return TRUE;
}

static gboolean handle_manager_modem_added(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, properties;
	const char *path;

	if (modem_obj_path != NULL)
		return TRUE;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter)
						!= DBUS_TYPE_OBJECT_PATH) {
		error("Unexpected signature in %s.%s signal",
					dbus_message_get_interface(msg),
					dbus_message_get_member(msg));
		return TRUE;
	}

	dbus_message_iter_get_basic(&iter, &path);
	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &properties);

	modem_added(path, &properties);

	return TRUE;
}

static gboolean handle_manager_modem_removed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *path;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_OBJECT_PATH, &path,
				DBUS_TYPE_INVALID)) {
		error("Unexpected signature in %s.%s signal",
					dbus_message_get_interface(msg),
					dbus_message_get_member(msg));
		return TRUE;
	}

	modem_removed(path);

	return TRUE;
}

static void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError err;
	dbus_int32_t level;
	int *value = user_data;

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		error("hald replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (dbus_message_get_args(reply, &err,
				DBUS_TYPE_INT32, &level,
				DBUS_TYPE_INVALID) == FALSE) {
		error("Unable to parse GetPropertyInteger reply: %s, %s",
							err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	*value = (int) level;

	if (value == &battchg_last)
		DBG("telephony-ofono: battery.charge_level.last_full"
					" is %d", *value);
	else if (value == &battchg_design)
		DBG("telephony-ofono: battery.charge_level.design"
					" is %d", *value);
	else
		DBG("telephony-ofono: battery.charge_level.current"
					" is %d", *value);

	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
		int new, max;

		if (battchg_last > 0)
			max = battchg_last;
		else
			max = battchg_design;

		new = battchg_cur * 5 / max;

		telephony_update_indicator(ofono_indicators, "battchg", new);
	}
done:
	dbus_message_unref(reply);
	remove_pending(call);
}

static void hal_get_integer(const char *path, const char *key, void *user_data)
{
	send_method_call("org.freedesktop.Hal", path,
			"org.freedesktop.Hal.Device",
			"GetPropertyInteger",
			hal_battery_level_reply, user_data,
			DBUS_TYPE_STRING, &key,
			DBUS_TYPE_INVALID);
}

static gboolean handle_hal_property_modified(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *path;
	DBusMessageIter iter, array;
	dbus_int32_t num_changes;

	path = dbus_message_get_path(msg);

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
		error("Unexpected signature in hal PropertyModified signal");
		return TRUE;
	}

	dbus_message_iter_get_basic(&iter, &num_changes);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature in hal PropertyModified signal");
		return TRUE;
	}

	dbus_message_iter_recurse(&iter, &array);

	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
		DBusMessageIter prop;
		const char *name;
		dbus_bool_t added, removed;

		dbus_message_iter_recurse(&array, &prop);

		if (!iter_get_basic_args(&prop,
					DBUS_TYPE_STRING, &name,
					DBUS_TYPE_BOOLEAN, &added,
					DBUS_TYPE_BOOLEAN, &removed,
					DBUS_TYPE_INVALID)) {
			error("Invalid hal PropertyModified parameters");
			break;
		}

		if (g_str_equal(name, "battery.charge_level.last_full"))
			hal_get_integer(path, name, &battchg_last);
		else if (g_str_equal(name, "battery.charge_level.current"))
			hal_get_integer(path, name, &battchg_cur);
		else if (g_str_equal(name, "battery.charge_level.design"))
			hal_get_integer(path, name, &battchg_design);

		dbus_message_iter_next(&array);
	}

	return TRUE;
}

static void add_watch(const char *sender, const char *path,
				const char *interface, const char *member,
				GDBusSignalFunction function)
{
	guint watch;

	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
					member, function, NULL, NULL);

	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
}

static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError err;
	DBusMessageIter iter, sub;
	int type;
	const char *path;

	DBG("begin of hal_find_device_reply()");
	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);

	if (dbus_set_error_from_message(&err, reply)) {
		error("hald replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	dbus_message_iter_init(reply, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature in hal_find_device_reply()");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &sub);

	type = dbus_message_iter_get_arg_type(&sub);

	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
		error("No hal device with battery capability found");
		goto done;
	}

	dbus_message_iter_get_basic(&sub, &path);

	DBG("telephony-ofono: found battery device at %s", path);

	add_watch(NULL, path, "org.freedesktop.Hal.Device",
			"PropertyModified", handle_hal_property_modified);

	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
done:
	dbus_message_unref(reply);
	remove_pending(call);
}

static void handle_service_connect(DBusConnection *conn, void *user_data)
{
	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);

	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
				OFONO_MANAGER_INTERFACE, "GetModems",
				get_modems_reply, NULL, DBUS_TYPE_INVALID);
}

static void handle_service_disconnect(DBusConnection *conn, void *user_data)
{
	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);

	if (modem_obj_path)
		modem_removed(modem_obj_path);
}

int telephony_init(void)
{
	const char *battery_cap = "battery";
	int ret;
	guint watch;

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);

	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
			"PropertyChanged", handle_modem_property_changed);
	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
			"PropertyChanged", handle_network_property_changed);
	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
			"ModemAdded", handle_manager_modem_added);
	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
			"ModemRemoved", handle_manager_modem_removed);
	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
			"CallAdded", handle_vcmanager_call_added);
	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
			"CallRemoved", handle_vcmanager_call_removed);

	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
						handle_service_connect,
						handle_service_disconnect,
						NULL, NULL);
	if (watch == 0)
		return -ENOMEM;

	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));

	ret = send_method_call("org.freedesktop.Hal",
				"/org/freedesktop/Hal/Manager",
				"org.freedesktop.Hal.Manager",
				"FindDeviceByCapability",
				hal_find_device_reply, NULL,
				DBUS_TYPE_STRING, &battery_cap,
				DBUS_TYPE_INVALID);
	if (ret < 0)
		return ret;

	DBG("telephony_init() successfully");

	return ret;
}

static void remove_watch(gpointer data)
{
	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
}

void telephony_exit(void)
{
	DBG("");

	g_free(last_dialed_number);
	last_dialed_number = NULL;

	if (modem_obj_path)
		modem_removed(modem_obj_path);

	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
	g_slist_free(watches);
	watches = NULL;

	g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
	g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
	g_slist_free(pending);
	pending = NULL;

	dbus_connection_unref(connection);
	connection = NULL;

	telephony_deinit();
}
