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

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

	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;

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

void telephony_call_hold_req(void *telephony_device, const char *cmd)
{
	DBG("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)
{
	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)
{
	DBG("telephony-ofono: got key press request for %s", keys);
	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;
		}
	}

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

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

	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;

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

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