/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2009       Intel Corporation
 *  Copyright (C) 2006-2007  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 "logging.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;
	char *number;
	guint watch;
};

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

#define OFONO_BUS_NAME "org.ofono"
#define OFONO_PATH "/"
#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"

static guint registration_watch = 0;
static guint voice_watch = 0;
static guint device_watch = 0;

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

/* Response and hold state
 * -1 = none
 *  0 = incoming call is put on hold in the AG
 *  1 = held incoming call is accepted in the AG
 *  2 = held incoming call is rejected in the AG
 */
static int response_and_hold = -1;

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

void telephony_device_connected(void *telephony_device)
{
	debug("telephony-ofono: device %p connected", telephony_device);
}

void telephony_device_disconnected(void *telephony_device)
{
	debug("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)
{
	response_and_hold = rh;

	telephony_response_and_hold_ind(response_and_hold);

	telephony_response_and_hold_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_last_dialed_number_req(void *telephony_device)
{
	debug("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);
	dbus_pending_call_unref(call);
	dbus_message_unref(msg);

	return 0;
}

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

	if ((vc = find_vc_with_status(CALL_STATUS_ACTIVE))) {
	} else if ((vc = find_vc_with_status(CALL_STATUS_DIALING))) {
	} else if ((vc = find_vc_with_status(CALL_STATUS_ALERTING))) {
	} else if ((vc = find_vc_with_status(CALL_STATUS_INCOMING))) {
	}

	if (!vc) {
		error("in telephony_terminate_call_req, no active call");
		telephony_terminate_call_rsp(telephony_device,
					CME_ERROR_NOT_ALLOWED);
		return;
	}

	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
					OFONO_VC_INTERFACE,
					"Hangup", NULL,
					NULL, DBUS_TYPE_INVALID);

	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_answer_call_req(void *telephony_device)
{
	struct voice_call *vc = find_vc_with_status(CALL_STATUS_INCOMING);
	int ret;

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

	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
			OFONO_VC_INTERFACE,
			"Answer", NULL,
			NULL, DBUS_TYPE_INVALID);

	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;

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

	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;

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

	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)
{
	debug("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;

	debug("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;

		direction = vc->originating ?
				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;

		telephony_list_current_call_ind(i, direction, vc->status,
					CALL_MODE_VOICE, CALL_MULTIPARTY_NO,
					vc->number, NUMBER_TYPE_TELEPHONY);
	}
	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_operator_selection_req(void *telephony_device)
{
	debug("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);
}

void telephony_call_hold_req(void *telephony_device, const char *cmd)
{
	debug("telephony-ofono: got call hold request %s", cmd);
	telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
}

void telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
{
	debug("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)
{
	debug("telephony-ofono: got key press request for %s", keys);
	telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
}

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 handle_registration_property(const char *property, DBusMessageIter sub)
{
	const char *status, *operator;
	unsigned int signals_bar;

	if (g_str_equal(property, "Status")) {
		dbus_message_iter_get_basic(&sub, &status);
		debug("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, "Operator")) {
		dbus_message_iter_get_basic(&sub, &operator);
		debug("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(&sub, &signals_bar);
		debug("SignalStrength is %d", signals_bar);
		net.signals_bar = signals_bar;
		telephony_update_indicator(ofono_indicators, "signal",
						(signals_bar + 20) / 21);
	}
}

static void get_registration_reply(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	DBusMessageIter iter, iter_entry;
	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
				AG_FEATURE_REJECT_A_CALL |
				AG_FEATURE_ENHANCED_CALL_STATUS |
				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;

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

	/* ARRAY -> ENTRY -> VARIANT*/
	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature in GetProperties return");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &iter_entry);

	if (dbus_message_iter_get_arg_type(&iter_entry)
					!= DBUS_TYPE_DICT_ENTRY) {
		error("Unexpected signature in GetProperties return");
		goto done;
	}

	while (dbus_message_iter_get_arg_type(&iter_entry)
					!= DBUS_TYPE_INVALID) {
		DBusMessageIter iter_property, sub;
		char *property;

		dbus_message_iter_recurse(&iter_entry, &iter_property);
		if (dbus_message_iter_get_arg_type(&iter_property)
					!= DBUS_TYPE_STRING) {
			error("Unexpected signature in GetProperties return");
			goto done;
		}

		dbus_message_iter_get_basic(&iter_property, &property);

		dbus_message_iter_next(&iter_property);
		dbus_message_iter_recurse(&iter_property, &sub);

		handle_registration_property(property, sub);

                dbus_message_iter_next(&iter_entry);
        }

	telephony_ready_ind(features, ofono_indicators,
				response_and_hold, chld_str);

done:
	dbus_message_unref(reply);
}

static int get_registration_and_signal_status()
{
	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
			OFONO_NETWORKREG_INTERFACE,
			"GetProperties", get_registration_reply,
			NULL, DBUS_TYPE_INVALID);
}

static void list_modem_reply(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	DBusMessageIter iter, iter_entry, iter_property, iter_arrary, sub;
	char *property, *modem_obj_path_local;
	int ret;

	debug("list_modem_reply is called\n");
	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 in ListModems return");
		goto done;
	}

	dbus_message_iter_recurse(&iter, &iter_entry);

	if (dbus_message_iter_get_arg_type(&iter_entry)
					!= DBUS_TYPE_DICT_ENTRY) {
		error("Unexpected signature in ListModems return 2, %c",
				dbus_message_iter_get_arg_type(&iter_entry));
		goto done;
	}

	dbus_message_iter_recurse(&iter_entry, &iter_property);

	dbus_message_iter_get_basic(&iter_property, &property);

	dbus_message_iter_next(&iter_property);
	dbus_message_iter_recurse(&iter_property, &iter_arrary);
	dbus_message_iter_recurse(&iter_arrary, &sub);
	while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {

		dbus_message_iter_get_basic(&sub, &modem_obj_path_local);
		modem_obj_path = g_strdup(modem_obj_path_local);
		debug("modem_obj_path is %p, %s\n", modem_obj_path,
						modem_obj_path);
		dbus_message_iter_next(&sub);
	}

	ret = get_registration_and_signal_status();
	if (ret < 0)
		error("get_registration_and_signal_status() failed(%d)", ret);
done:
	dbus_message_unref(reply);
}

static gboolean handle_registration_property_changed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, sub;
	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);
	debug("in handle_registration_property_changed(),"
					" the property is %s", property);

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

	handle_registration_property(property, sub);

	return TRUE;
}

static void vc_getproperties_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError err;
	DBusMessageIter iter, iter_entry;
	const char *path = user_data;
	struct voice_call *vc;

	debug("in vc_getproperties_reply");

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

	vc = find_vc(path);
	if (!vc) {
		error("in vc_getproperties_reply, vc is NULL");
		goto done;
	}

	dbus_message_iter_init(reply, &iter);

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

	dbus_message_iter_recurse(&iter, &iter_entry);

	if (dbus_message_iter_get_arg_type(&iter_entry)
			!= DBUS_TYPE_DICT_ENTRY) {
		error("Unexpected signature in vc_getproperties_reply()");
		goto done;
	}

	while (dbus_message_iter_get_arg_type(&iter_entry)
			!= DBUS_TYPE_INVALID) {
		DBusMessageIter iter_property, sub;
		char *property, *cli, *state;

		dbus_message_iter_recurse(&iter_entry, &iter_property);
		if (dbus_message_iter_get_arg_type(&iter_property)
				!= DBUS_TYPE_STRING) {
			error("Unexpected signature in"
					" vc_getproperties_reply()");
			goto done;
		}

		dbus_message_iter_get_basic(&iter_property, &property);

		dbus_message_iter_next(&iter_property);
		dbus_message_iter_recurse(&iter_property, &sub);
		if (g_str_equal(property, "LineIdentification")) {
			dbus_message_iter_get_basic(&sub, &cli);
			debug("in vc_getproperties_reply(), cli is %s", cli);
			vc->number = g_strdup(cli);
		} else if (g_str_equal(property, "State")) {
			dbus_message_iter_get_basic(&sub, &state);
			debug("in vc_getproperties_reply(),"
					" state is %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;
		}

		dbus_message_iter_next(&iter_entry);
	}

	switch (vc->status) {
	case CALL_STATUS_INCOMING:
		printf("in CALL_STATUS_INCOMING: case\n");
		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:
		printf("in CALL_STATUS_DIALING: case\n");
		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:
		printf("in CALL_STATUS_ALERTING: case\n");
		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:
		debug("in CALL_STATUS_WAITING: case");
		vc->originating = FALSE;
		telephony_update_indicator(ofono_indicators, "callsetup",
					EV_CALLSETUP_INCOMING);
		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
		break;
	}
done:
	dbus_message_unref(reply);
}

static void vc_free(struct voice_call *vc)
{
	if (!vc)
		return;

	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;

	debug("in handle_vc_property_changed, obj_path is %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);
	debug("in handle_vc_property_changed(), the property is %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);
		debug("in handle_vc_property_changed(), State is %s", state);
		if (g_str_equal(state, "disconnected")) {
			printf("in disconnected case\n");
			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();
			calls = g_slist_remove(calls, vc);
			vc_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;
			debug("vc status is CALL_STATUS_ACTIVE");
		} else if (g_str_equal(state, "alerting")) {
			telephony_update_indicator(ofono_indicators,
					 "callsetup", EV_CALLSETUP_ALERTING);
			vc->status = CALL_STATUS_ALERTING;
			debug("vc status is CALL_STATUS_ALERTING");
		} 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;
			debug("vc status is CALL_STATUS_INCOMING");
		}
	}

	return TRUE;
}

static gboolean handle_vcmanager_property_changed(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, sub, array;
	const char *property, *vc_obj_path = NULL;
	struct voice_call *vc, *vc_new = NULL;

	debug("in handle_vcmanager_property_changed");

	dbus_message_iter_init(msg, &iter);

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

	dbus_message_iter_get_basic(&iter, &property);
	debug("in handle_vcmanager_property_changed(),"
				" the property is %s", property);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &sub);
	if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY) {
		error("Unexpected signature in vcmanager"
					" PropertyChanged signal");
		return TRUE;
	}
	dbus_message_iter_recurse(&sub, &array);
	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
		dbus_message_iter_get_basic(&array, &vc_obj_path);
		vc = find_vc(vc_obj_path);
		if (vc) {
			debug("in handle_vcmanager_property_changed,"
					" found an existing vc");
		} else {
			vc_new = g_new0(struct voice_call, 1);
			vc_new->obj_path = g_strdup(vc_obj_path);
			calls = g_slist_append(calls, vc_new);
			device_watch = g_dbus_add_signal_watch(connection,
					NULL, vc_obj_path,
					OFONO_VC_INTERFACE,
					"PropertyChanged",
					handle_vc_property_changed,
					vc_new, NULL);
		}
		dbus_message_iter_next(&array);
	}

	if (!vc_new)
		return TRUE;

	send_method_call(OFONO_BUS_NAME, vc_new->obj_path,
				OFONO_VC_INTERFACE,
				"GetProperties", vc_getproperties_reply,
				vc_new->obj_path, DBUS_TYPE_INVALID);

	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_message_get_args(reply, NULL,
				DBUS_TYPE_INT32, &level,
				DBUS_TYPE_INVALID);

	*value = (int) level;

	if (value == &battchg_last)
		debug("telephony-ofono: battery.charge_level.last_full"
					" is %d", *value);
	else if (value == &battchg_design)
		debug("telephony-ofono: battery.charge_level.design"
					" is %d", *value);
	else
		debug("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);
}

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 hal_find_device_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError err;
	DBusMessageIter iter, sub;
	int type;
	const char *path;

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

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

	device_watch = g_dbus_add_signal_watch(connection, NULL, path,
					"org.freedesktop.Hal.Device",
					"PropertyModified",
					handle_hal_property_modified,
					NULL, NULL);

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

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

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);

	registration_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
					OFONO_NETWORKREG_INTERFACE,
					"PropertyChanged",
					handle_registration_property_changed,
					NULL, NULL);

	voice_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
					OFONO_VCMANAGER_INTERFACE,
					"PropertyChanged",
					handle_vcmanager_property_changed,
					NULL, NULL);

	ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
				OFONO_MANAGER_INTERFACE, "GetProperties",
				list_modem_reply, NULL, DBUS_TYPE_INVALID);
	if (ret < 0)
		return ret;

	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;

	debug("telephony_init() successfully");

	return ret;
}

void telephony_exit(void)
{
	g_free(net.operator_name);

	g_free(modem_obj_path);
	g_free(last_dialed_number);

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

	g_dbus_remove_watch(connection, registration_watch);
	g_dbus_remove_watch(connection, voice_watch);
	g_dbus_remove_watch(connection, device_watch);

	dbus_connection_unref(connection);
	connection = NULL;
}
