/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2009       Intel Corporation
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2009  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;
};

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"

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

static inline DBusMessage *invalid_args(DBusMessage *msg)
{
	return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
					"Invalid arguments in method call");
}

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)
{
	char *clir = "default";
	int ret;

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

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

	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)
{
	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 void handle_networkregistration_property_changed(DBusMessage *msg,
					const char *call_path)
{
	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;
	}
	dbus_message_iter_get_basic(&iter, &property);
	debug("in handle_networkregistration_property_changed(),"
					" the property is %s", property);

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

	handle_registration_property(property, sub);
}

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 handle_vcmanager_property_changed(DBusMessage *msg,
						const char *obj_path)
{
	DBusMessageIter iter, sub, array;
	const char *property, *vc_obj_path = NULL;
	struct voice_call *vc = NULL, *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;
	}

	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;
	}
	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);
		}
		dbus_message_iter_next(&array);
	}

	if (!vc_new)
		return;

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

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

	g_free(vc->obj_path);
	g_free(vc->number);
	g_free(vc);
}

static void handle_vc_property_changed(DBusMessage *msg, const char *obj_path)
{
	DBusMessageIter iter, sub;
	const char *property, *state;
	struct voice_call *vc = NULL;

	debug("in handle_vc_property_changed, obj_path is %s", obj_path);

	vc = find_vc(obj_path);

	if (!vc)
		return;

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

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

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

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

	snprintf(match_string, sizeof(match_string),
			"type='signal',"
			"path='%s',"
			"interface='org.freedesktop.Hal.Device',"
			"member='PropertyModified'", path);
	dbus_bus_add_match(connection, match_string, 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);
}

static void handle_hal_property_modified(DBusMessage *msg)
{
	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;
	}

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

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

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

	if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (dbus_message_is_signal(msg, OFONO_NETWORKREG_INTERFACE,
				"PropertyChanged"))
		handle_networkregistration_property_changed(msg, path);
	else if (dbus_message_is_signal(msg, OFONO_VCMANAGER_INTERFACE,
				"PropertyChanged"))
		handle_vcmanager_property_changed(msg, path);
	else if (dbus_message_is_signal(msg, OFONO_VC_INTERFACE,
				"PropertyChanged"))
		handle_vc_property_changed(msg, path);
	else if (dbus_message_is_signal(msg, "org.freedesktop.Hal.Device",
				"PropertyModified"))
		handle_hal_property_modified(msg);

	debug("signal_filter is called, path is %s\n", path);
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

int telephony_init(void)
{
	const char *battery_cap = "battery";
	char match_string[128];
	int ret;

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);

	if (!dbus_connection_add_filter(connection, signal_filter,
					NULL, NULL)) {
		error("telephony-ofono: Can't add signal filter");
		return -EIO;
	}

	snprintf(match_string, sizeof(match_string), "type=signal,interface=%s",
				OFONO_NETWORKREG_INTERFACE);
	dbus_bus_add_match(connection, match_string, NULL);

	snprintf(match_string, sizeof(match_string), "type=signal,interface=%s",
				OFONO_VCMANAGER_INTERFACE);
	dbus_bus_add_match(connection, match_string, NULL);

	snprintf(match_string, sizeof(match_string), "type=signal,interface=%s",
				OFONO_VC_INTERFACE);
	dbus_bus_add_match(connection, match_string, 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;

	dbus_connection_remove_filter(connection, signal_filter, NULL);

	dbus_connection_unref(connection);
	connection = NULL;
}
