/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
 *  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *  Copyright (C) 2011-2014  BMW Car IT GmbH.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 <errno.h>
#include <stdlib.h>

#include <gdbus.h>
#include <string.h>
#include <stdint.h>

#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/device.h>
#include <connman/network.h>
#include <connman/inet.h>
#include <connman/dbus.h>
#include <connman/log.h>
#include <connman/technology.h>

#include "mcc.h"

#define OFONO_SERVICE			"org.ofono"

#define OFONO_MANAGER_INTERFACE		OFONO_SERVICE ".Manager"
#define OFONO_MODEM_INTERFACE		OFONO_SERVICE ".Modem"
#define OFONO_SIM_INTERFACE			OFONO_SERVICE ".SimManager"
#define OFONO_NETREG_INTERFACE		OFONO_SERVICE ".NetworkRegistration"
#define OFONO_CM_INTERFACE			OFONO_SERVICE ".ConnectionManager"
#define OFONO_CONTEXT_INTERFACE		OFONO_SERVICE ".ConnectionContext"
#define OFONO_CDMA_CM_INTERFACE		OFONO_SERVICE ".cdma.ConnectionManager"
#define OFONO_CDMA_NETREG_INTERFACE	OFONO_SERVICE ".cdma.NetworkRegistration"

#define MODEM_ADDED				"ModemAdded"
#define MODEM_REMOVED			"ModemRemoved"
#define PROPERTY_CHANGED		"PropertyChanged"
#define CONTEXT_ADDED			"ContextAdded"
#define CONTEXT_REMOVED			"ContextRemoved"

#define GET_PROPERTIES			"GetProperties"
#define SET_PROPERTY			"SetProperty"
#define GET_MODEMS				"GetModems"
#define GET_CONTEXTS			"GetContexts"

#define TIMEOUT 40000

enum ofono_api {
	OFONO_API_SIM =		0x1,
	OFONO_API_NETREG =	0x2,
	OFONO_API_CM =		0x4,
	OFONO_API_CDMA_NETREG =	0x8,
	OFONO_API_CDMA_CM =	0x10,
};

/*
 * The way this plugin works is following:
 *
 *   powered -> SubscriberIdentity or Online = True -> gprs, context ->
 *     attached -> netreg -> ready
 *
 * Depending on the modem type, this plugin will behave differently.
 *
 * GSM working flow:
 *
 * When a new modem appears, the plugin always powers it up. This
 * allows the plugin to create a connman_device. The core will call
 * modem_enable() if the technology is enabled. modem_enable() will
 * then set the modem online. If the technology is disabled then
 * modem_disable() will just set the modem offline. The modem is
 * always kept powered all the time.
 *
 * After setting the modem online the plugin waits for the
 * ConnectionManager and ConnectionContext to appear. When the context
 * signals that it is attached and the NetworkRegistration interface
 * appears, a new Service will be created and registered at the core.
 *
 * When asked to connect to the network (network_connect()) the plugin
 * will set the Active property on the context. If this operation is
 * successful the modem is connected to the network. oFono will inform
 * the plugin about IP configuration through the updating the context's
 * properties.
 *
 * CDMA working flow:
 *
 * When a new modem appears, the plugin always powers it up. This
 * allows the plugin to create connman_device either using IMSI either
 * using modem Serial if the modem got a SIM interface or not.
 *
 * As for GSM, the core will call modem_enable() if the technology
 * is enabled. modem_enable() will then set the modem online.
 * If the technology is disabled then modem_disable() will just set the
 * modem offline. The modem is always kept powered all the time.
 *
 * After setting the modem online the plugin waits for CdmaConnectionManager
 * interface to appear. Then, once CdmaNetworkRegistration appears, a new
 * Service will be created and registered at the core.
 *
 * When asked to connect to the network (network_connect()) the plugin
 * will power up the CdmaConnectionManager interface.
 * If the operation is successful the modem is connected to the network.
 * oFono will inform the plugin about IP configuration through the
 * updating CdmaConnectionManager settings properties.
 */

static DBusConnection *connection;

static GHashTable *modem_hash;
static GHashTable *context_hash;

struct network_context {
	char *path;
	int index;

	enum connman_ipconfig_method ipv4_method;
	struct connman_ipaddress *ipv4_address;
	char *ipv4_nameservers;

	enum connman_ipconfig_method ipv6_method;
	struct connman_ipaddress *ipv6_address;
	char *ipv6_nameservers;
};

struct modem_data {
	char *path;

	struct connman_device *device;
	struct connman_network *network;

	struct network_context *context;

	/* Modem Interface */
	char *serial;
	bool powered;
	bool online;
	uint8_t interfaces;
	bool ignore;

	bool set_powered;

	/* CDMA ConnectionManager Interface */
	bool cdma_cm_powered;

	/* ConnectionManager Interface */
	bool attached;
	bool cm_powered;

	/* ConnectionContext Interface */
	bool active;
	bool valid_apn; /* APN is 'valid' if length > 0 */

	/* SimManager Interface */
	char *imsi;

	/* Netreg Interface */
	char *name;
	uint8_t strength;
	uint8_t data_strength; /* 1xEVDO signal strength */
	bool registered;
	bool roaming;

	/* pending calls */
	DBusPendingCall	*call_set_property;
	DBusPendingCall	*call_get_properties;
	DBusPendingCall *call_get_contexts;
};

static const char *api2string(enum ofono_api api)
{
	switch (api) {
	case OFONO_API_SIM:
		return "sim";
	case OFONO_API_NETREG:
		return "netreg";
	case OFONO_API_CM:
		return "cm";
	case OFONO_API_CDMA_NETREG:
		return "cdma-netreg";
	case OFONO_API_CDMA_CM:
		return "cmda-cm";
	}

	return "unknown";
}

static char *get_ident(const char *path)
{
	char *pos;

	if (*path != '/')
		return NULL;

	pos = strrchr(path, '/');
	if (!pos)
		return NULL;

	return pos + 1;
}

static struct network_context *network_context_alloc(const char *path)
{
	struct network_context *context;

	context = g_try_new0(struct network_context, 1);
	if (!context)
		return NULL;

	context->path = g_strdup(path);
	context->index = -1;

	context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
	context->ipv4_address = NULL;
	context->ipv4_nameservers = NULL;

	context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
	context->ipv6_address = NULL;
	context->ipv6_nameservers = NULL;

	return context;
}

static void network_context_free(struct network_context *context)
{
	g_free(context->path);

	connman_ipaddress_free(context->ipv4_address);
	g_free(context->ipv4_nameservers);

	connman_ipaddress_free(context->ipv6_address);
	g_free(context->ipv6_nameservers);

	free(context);
}

static void set_connected(struct modem_data *modem)
{
	struct connman_service *service;
	bool setip = false;
	enum connman_ipconfig_method method;
	char *nameservers;
	int index;

	DBG("%s", modem->path);

	index = modem->context->index;

	method = modem->context->ipv4_method;
	if (index < 0 || (!modem->context->ipv4_address &&
				method == CONNMAN_IPCONFIG_METHOD_FIXED)) {
		connman_error("Invalid index and/or address");
		return;
	}

	service = connman_service_lookup_from_network(modem->network);
	if (!service)
		return;

	connman_service_create_ip4config(service, index);
	connman_network_set_ipv4_method(modem->network, method);

	if (method == CONNMAN_IPCONFIG_METHOD_FIXED ||
			method == CONNMAN_IPCONFIG_METHOD_DHCP)	{
		setip = true;
	}

	if (method == CONNMAN_IPCONFIG_METHOD_FIXED) {
		connman_network_set_ipaddress(modem->network,
						modem->context->ipv4_address);
	}

	method = modem->context->ipv6_method;
	connman_service_create_ip6config(service, index);
	connman_network_set_ipv6_method(modem->network, method);

	if (method == CONNMAN_IPCONFIG_METHOD_AUTO) {
		setip = true;
	}

	/* Set the nameservers */
	if (modem->context->ipv4_nameservers &&
			modem->context->ipv6_nameservers) {
		nameservers = g_strdup_printf("%s %s",
					modem->context->ipv4_nameservers,
					modem->context->ipv6_nameservers);
		connman_network_set_nameservers(modem->network, nameservers);
		g_free(nameservers);
	} else if (modem->context->ipv4_nameservers) {
		connman_network_set_nameservers(modem->network,
					modem->context->ipv4_nameservers);
	} else if (modem->context->ipv6_nameservers) {
		connman_network_set_nameservers(modem->network,
					modem->context->ipv6_nameservers);
	}

	if (setip) {
		connman_network_set_index(modem->network, index);
		connman_network_set_connected(modem->network, true);
	}
}

static void set_disconnected(struct modem_data *modem)
{
	DBG("%s", modem->path);

	if (modem->network)
		connman_network_set_connected(modem->network, false);

	if (modem->context) {
		g_free(modem->context->ipv4_nameservers);
		modem->context->ipv4_nameservers = NULL;
		if (modem->context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
			modem->context->ipv4_method =
					CONNMAN_IPCONFIG_METHOD_UNKNOWN;

		g_free(modem->context->ipv6_nameservers);
		modem->context->ipv6_nameservers = NULL;
		if (modem->context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
			modem->context->ipv6_method =
					CONNMAN_IPCONFIG_METHOD_UNKNOWN;
	}
}

typedef void (*set_property_cb)(struct modem_data *data,
				bool success);
typedef void (*get_properties_cb)(struct modem_data *data,
				DBusMessageIter *dict);

struct property_info {
	struct modem_data *modem;
	const char *path;
	const char *interface;
	const char *property;
	set_property_cb set_property_cb;
	get_properties_cb get_properties_cb;
};

static void set_property_reply(DBusPendingCall *call, void *user_data)
{
	struct property_info *info = user_data;
	DBusMessage *reply;
	DBusError error;
	bool success = true;

	DBG("%s path %s %s.%s", info->modem->path,
		info->path, info->interface, info->property);

	info->modem->call_set_property = NULL;

	dbus_error_init(&error);

	reply = dbus_pending_call_steal_reply(call);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("Failed to change property: %s %s.%s: %s %s",
				info->path, info->interface, info->property,
				error.name, error.message);
		dbus_error_free(&error);
		success = false;
	}

	if (info->set_property_cb)
		(*info->set_property_cb)(info->modem, success);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static int set_property(struct modem_data *modem,
			const char *path, const char *interface,
			const char *property, int type, void *value,
			set_property_cb notify)
{
	DBusMessage *message;
	DBusMessageIter iter;
	struct property_info *info;

	DBG("%s path %s %s.%s", modem->path, path, interface, property);

	if (modem->call_set_property) {
		DBG("Cancel pending SetProperty");
		dbus_pending_call_cancel(modem->call_set_property);
		dbus_pending_call_unref(modem->call_set_property);
		modem->call_set_property = NULL;
	}

	message = dbus_message_new_method_call(OFONO_SERVICE, path,
					interface, SET_PROPERTY);
	if (!message)
		return -ENOMEM;

	dbus_message_iter_init_append(message, &iter);
	connman_dbus_property_append_basic(&iter, property, type, value);

	if (!dbus_connection_send_with_reply(connection, message,
					&modem->call_set_property, TIMEOUT)) {
		connman_error("Failed to change property: %s %s.%s",
				path, interface, property);
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!modem->call_set_property) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	info = g_try_new0(struct property_info, 1);
	if (!info) {
		dbus_message_unref(message);
		return -ENOMEM;
	}

	info->modem = modem;
	info->path = path;
	info->interface = interface;
	info->property = property;
	info->set_property_cb = notify;

	dbus_pending_call_set_notify(modem->call_set_property,
					set_property_reply, info, g_free);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static void get_properties_reply(DBusPendingCall *call, void *user_data)
{
	struct property_info *info = user_data;
	DBusMessageIter array, dict;
	DBusMessage *reply;
	DBusError error;

	DBG("%s path %s %s", info->modem->path, info->path, info->interface);

	info->modem->call_get_properties = NULL;

	dbus_error_init(&error);

	reply = dbus_pending_call_steal_reply(call);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("Failed to get properties: %s %s: %s %s",
				info->path, info->interface,
				error.name, error.message);
		dbus_error_free(&error);

		goto done;
	}

	if (!dbus_message_iter_init(reply, &array))
		goto done;

	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
		goto done;

	dbus_message_iter_recurse(&array, &dict);

	if (info->get_properties_cb)
		(*info->get_properties_cb)(info->modem, &dict);

done:

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static int get_properties(const char *path, const char *interface,
				get_properties_cb notify,
				struct modem_data *modem)
{
	DBusMessage *message;
	struct property_info *info;

	DBG("%s path %s %s", modem->path, path, interface);

	if (modem->call_get_properties) {
		connman_error("Pending GetProperties");
		return -EBUSY;
	}

	message = dbus_message_new_method_call(OFONO_SERVICE, path,
					interface, GET_PROPERTIES);
	if (!message)
		return -ENOMEM;

	if (!dbus_connection_send_with_reply(connection, message,
					&modem->call_get_properties, TIMEOUT)) {
		connman_error("Failed to call %s.GetProperties()", interface);
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!modem->call_get_properties) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	info = g_try_new0(struct property_info, 1);
	if (!info) {
		dbus_message_unref(message);
		return -ENOMEM;
	}

	info->modem = modem;
	info->path = path;
	info->interface = interface;
	info->get_properties_cb = notify;

	dbus_pending_call_set_notify(modem->call_get_properties,
					get_properties_reply, info, g_free);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static void context_set_active_reply(struct modem_data *modem,
					bool success)
{
	DBG("%s", modem->path);

	if (success) {
		/*
		 * Don't handle do anything on success here. oFono will send
		 * the change via PropertyChanged singal.
		 */
		return;
	}

	/*
	 * Active = True might fail due a timeout. That means oFono
	 * still tries to go online. If we retry to set Active = True,
	 * we just get a InProgress error message. Should we power
	 * cycle the modem in such cases?
	 */

	if (!modem->network) {
		/*
		 * In the case where we power down the device
		 * we don't wait for the reply, therefore the network
		 * might already be gone.
		 */
		return;
	}

	connman_network_set_error(modem->network,
				CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
}

static int context_set_active(struct modem_data *modem,
				dbus_bool_t active)
{
	int err;

	DBG("%s active %d", modem->path, active);

	err = set_property(modem, modem->context->path,
				OFONO_CONTEXT_INTERFACE,
				"Active", DBUS_TYPE_BOOLEAN,
				&active,
				context_set_active_reply);

	if (!active && err == -EINPROGRESS)
		return 0;

	return err;
}

static void cdma_cm_set_powered_reply(struct modem_data *modem,
					bool success)
{
	DBG("%s", modem->path);

	if (success) {
		/*
		 * Don't handle do anything on success here. oFono will send
		 * the change via PropertyChanged singal.
		 */
		return;
	}

	/*
	 * Powered = True might fail due a timeout. That means oFono
	 * still tries to go online. If we retry to set Powered = True,
	 * we just get a InProgress error message. Should we power
	 * cycle the modem in such cases?
	 */

	if (!modem->network) {
		/*
		 * In the case where we power down the device
		 * we don't wait for the reply, therefore the network
		 * might already be gone.
		 */
		return;
	}

	connman_network_set_error(modem->network,
				CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
}

static int cdma_cm_set_powered(struct modem_data *modem, dbus_bool_t powered)
{
	int err;

	DBG("%s powered %d", modem->path, powered);

	err = set_property(modem, modem->path, OFONO_CDMA_CM_INTERFACE,
				"Powered", DBUS_TYPE_BOOLEAN,
				&powered,
				cdma_cm_set_powered_reply);

	if (!powered && err == -EINPROGRESS)
		return 0;

	return err;
}

static int modem_set_online(struct modem_data *modem, dbus_bool_t online)
{
	DBG("%s online %d", modem->path, online);

	return set_property(modem, modem->path,
				OFONO_MODEM_INTERFACE,
				"Online", DBUS_TYPE_BOOLEAN,
				&online,
				NULL);
}

static int cm_set_powered(struct modem_data *modem, dbus_bool_t powered)
{
	int err;

	DBG("%s powered %d", modem->path, powered);

	err = set_property(modem, modem->path,
				OFONO_CM_INTERFACE,
				"Powered", DBUS_TYPE_BOOLEAN,
				&powered,
				NULL);

	if (!powered && err == -EINPROGRESS)
		return 0;

	return err;
}

static int modem_set_powered(struct modem_data *modem, dbus_bool_t powered)
{
	int err;

	DBG("%s powered %d", modem->path, powered);

	modem->set_powered = powered;

	err = set_property(modem, modem->path,
				OFONO_MODEM_INTERFACE,
				"Powered", DBUS_TYPE_BOOLEAN,
				&powered,
				NULL);

	if (!powered && err == -EINPROGRESS)
		return 0;

	return err;
}

static bool has_interface(uint8_t interfaces,
					enum ofono_api api)
{
	if ((interfaces & api) == api)
		return true;

	return false;
}

static uint8_t extract_interfaces(DBusMessageIter *array)
{
	DBusMessageIter entry;
	uint8_t interfaces = 0;

	dbus_message_iter_recurse(array, &entry);

	while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
		const char *name;

		dbus_message_iter_get_basic(&entry, &name);

		if (g_str_equal(name, OFONO_SIM_INTERFACE))
			interfaces |= OFONO_API_SIM;
		else if (g_str_equal(name, OFONO_NETREG_INTERFACE))
			interfaces |= OFONO_API_NETREG;
		else if (g_str_equal(name, OFONO_CM_INTERFACE))
			interfaces |= OFONO_API_CM;
		else if (g_str_equal(name, OFONO_CDMA_CM_INTERFACE))
			interfaces |= OFONO_API_CDMA_CM;
		else if (g_str_equal(name, OFONO_CDMA_NETREG_INTERFACE))
			interfaces |= OFONO_API_CDMA_NETREG;

		dbus_message_iter_next(&entry);
	}

	return interfaces;
}

static char *extract_nameservers(DBusMessageIter *array)
{
	DBusMessageIter entry;
	char *nameservers = NULL;
	char *tmp;

	dbus_message_iter_recurse(array, &entry);

	while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
		const char *nameserver;

		dbus_message_iter_get_basic(&entry, &nameserver);

		if (!nameservers) {
			nameservers = g_strdup(nameserver);
		} else {
			tmp = nameservers;
			nameservers = g_strdup_printf("%s %s", tmp, nameserver);
			g_free(tmp);
		}

		dbus_message_iter_next(&entry);
	}

	return nameservers;
}

static void extract_ipv4_settings(DBusMessageIter *array,
				struct network_context *context)
{
	DBusMessageIter dict;
	char *address = NULL, *netmask = NULL, *gateway = NULL;
	char *nameservers = NULL;
	const char *interface = NULL;
	int index = -1;

	connman_ipaddress_free(context->ipv4_address);
	context->ipv4_address = NULL;
	context->index = -1;

	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(array, &dict);

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

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

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

		if (g_str_equal(key, "Interface")) {
			dbus_message_iter_get_basic(&value, &interface);

			DBG("Interface %s", interface);

			index = connman_inet_ifindex(interface);

			DBG("index %d", index);
		} else if (g_str_equal(key, "Method")) {
			dbus_message_iter_get_basic(&value, &val);

			DBG("Method %s", val);

			if (g_strcmp0(val, "static") == 0)
				context->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
			else if (g_strcmp0(val, "dhcp") == 0)
				context->ipv4_method = CONNMAN_IPCONFIG_METHOD_DHCP;

		} else if (g_str_equal(key, "Address")) {
			dbus_message_iter_get_basic(&value, &val);

			address = g_strdup(val);

			DBG("Address %s", address);
		} else if (g_str_equal(key, "Netmask")) {
			dbus_message_iter_get_basic(&value, &val);

			netmask = g_strdup(val);

			DBG("Netmask %s", netmask);
		} else if (g_str_equal(key, "DomainNameServers")) {
			nameservers = extract_nameservers(&value);

			DBG("Nameservers %s", nameservers);
		} else if (g_str_equal(key, "Gateway")) {
			dbus_message_iter_get_basic(&value, &val);

			gateway = g_strdup(val);

			DBG("Gateway %s", gateway);
		}

		dbus_message_iter_next(&dict);
	}

	if (index < 0)
		goto out;

	context->index = index;

	if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_FIXED)
		goto out;

	context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
	if (!context->ipv4_address) {
		context->index = -1;
		goto out;
	}

	connman_ipaddress_set_ipv4(context->ipv4_address, address,
				netmask, gateway);

	g_free(context->ipv4_nameservers);
	context->ipv4_nameservers = nameservers;

out:
	if (context->ipv4_nameservers != nameservers)
		g_free(nameservers);

	g_free(address);
	g_free(netmask);
	g_free(gateway);
}

static void extract_ipv6_settings(DBusMessageIter *array,
				struct network_context *context)
{
	DBusMessageIter dict;
	char *address = NULL, *gateway = NULL;
	unsigned char prefix_length = 0;
	char *nameservers = NULL;
	const char *interface = NULL;
	int index = -1;

	connman_ipaddress_free(context->ipv6_address);
	context->ipv6_address = NULL;
	context->index = -1;

	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(array, &dict);

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

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

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

		if (g_str_equal(key, "Interface")) {
			dbus_message_iter_get_basic(&value, &interface);

			DBG("Interface %s", interface);

			index = connman_inet_ifindex(interface);

			DBG("index %d", index);
		} else if (g_str_equal(key, "Address")) {
			dbus_message_iter_get_basic(&value, &val);

			address = g_strdup(val);

			DBG("Address %s", address);
		} else if (g_str_equal(key, "PrefixLength")) {
			dbus_message_iter_get_basic(&value, &prefix_length);

			DBG("prefix length %d", prefix_length);
		} else if (g_str_equal(key, "DomainNameServers")) {
			nameservers = extract_nameservers(&value);

			DBG("Nameservers %s", nameservers);
		} else if (g_str_equal(key, "Gateway")) {
			dbus_message_iter_get_basic(&value, &val);

			gateway = g_strdup(val);

			DBG("Gateway %s", gateway);
		}

		dbus_message_iter_next(&dict);
	}

	if (index < 0)
		goto out;

	context->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO;

	context->ipv6_address =
		connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
	if (!context->ipv6_address)
		goto out;

	context->index = index;
	connman_ipaddress_set_ipv6(context->ipv6_address, address,
				prefix_length, gateway);

	g_free(context->ipv6_nameservers);
	context->ipv6_nameservers = nameservers;

out:
	if (context->ipv6_nameservers != nameservers)
		g_free(nameservers);

	g_free(address);
	g_free(gateway);
}

static void update_device_ident(struct connman_device *device, struct modem_data *modem)
{
	const char unknown_ident[] = "UNKNOWN";
	char *ident = NULL;

	if (!device)
		return;

	if (modem->imsi)
		ident = modem->imsi;
	else if (modem->serial)
		ident = modem->serial;
	else
		ident = unknown_ident;

	if (!connman_dbus_validate_ident(ident))
		ident = connman_dbus_encode_string(ident);
	else
		ident = g_strdup(ident);

	connman_device_set_ident(device, ident);

	g_free(ident);
}

static void create_device(struct modem_data *modem)
{
	struct connman_device *device;

	DBG("%s", modem->path);

	device = connman_device_create("ofono", CONNMAN_DEVICE_TYPE_CELLULAR);
	if (!device)
		goto out;

	DBG("device %p", device);

	update_device_ident(device, modem);

	connman_device_set_string(device, "Path", modem->path);

	connman_device_set_data(device, modem);

	if (connman_device_register(device) < 0) {
		connman_error("Failed to register cellular device");
		connman_device_unref(device);
		goto out;
	}

	modem->device = device;

	connman_device_set_powered(modem->device, modem->online);

out:
	return;
}

static void destroy_device(struct modem_data *modem)
{
	DBG("%s", modem->path);

	connman_device_set_powered(modem->device, false);

	if (modem->network) {
		connman_device_remove_network(modem->device, modem->network);
		connman_network_unref(modem->network);
		modem->network = NULL;
	}

	connman_device_unregister(modem->device);
	connman_device_unref(modem->device);

	modem->device = NULL;
}

static void add_network(struct modem_data *modem)
{
	const char *group;

	DBG("%s", modem->path);

	if (modem->network)
		return;

	modem->network = connman_network_create(modem->context->path,
						CONNMAN_NETWORK_TYPE_CELLULAR);
	if (!modem->network)
		return;

	DBG("network %p", modem->network);

	connman_network_set_data(modem->network, modem);

	connman_network_set_string(modem->network, "Path",
					modem->context->path);

	if (modem->name)
		connman_network_set_name(modem->network, modem->name);
	else
		connman_network_set_name(modem->network, "");

	connman_network_set_strength(modem->network, modem->strength);

	group = get_ident(modem->context->path);
	connman_network_set_group(modem->network, group);

	connman_network_set_bool(modem->network, "Roaming",
					modem->roaming);

	if (connman_device_add_network(modem->device, modem->network) < 0) {
		connman_network_unref(modem->network);
		modem->network = NULL;
		return;
	}
}

static void remove_network(struct modem_data *modem)
{
	DBG("%s", modem->path);

	if (!modem->network)
		return;

	DBG("network %p", modem->network);

	connman_device_remove_network(modem->device, modem->network);
	connman_network_unref(modem->network);
	modem->network = NULL;
}

static int set_context_ipconfig(struct network_context *context,
				const char *protocol)
{
	DBG("context %p protocol %s", context, protocol);

	if (!context || !protocol)
		return -EINVAL;

	if (g_str_equal(protocol, "ip")) {
		if (context->ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF)
			context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;

		context->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;

		connman_ipaddress_free(context->ipv6_address);
		context->ipv6_address = NULL;

	} else if (g_str_equal(protocol, "ipv6")) {
		if (context->ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF)
			context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;

		context->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;

		connman_ipaddress_free(context->ipv4_address);
		context->ipv4_address = NULL;

	} else if (g_str_equal(protocol, "dual")) {
		if (context->ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF)
			context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;

		if (context->ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF)
			context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
	}

	DBG("ipv4 method %d ipv6 method %d", context->ipv4_method,
		context->ipv6_method);

	return 0;
}

static int add_cm_context(struct modem_data *modem, const char *context_path,
				DBusMessageIter *dict)
{
	const char *context_type = NULL;
	struct network_context *context = NULL;
	dbus_bool_t active = FALSE;
	const char *ip_protocol = NULL;

	DBG("%s context path %s", modem->path, context_path);

	if (modem->context) {
		/*
		 * We have already assigned a context to this modem
		 * and we do only support one Internet context.
		 */
		return -EALREADY;
	}

	context = network_context_alloc(context_path);
	if (!context)
		return -ENOMEM;

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

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

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

		if (g_str_equal(key, "Type")) {
			dbus_message_iter_get_basic(&value, &context_type);

			DBG("%s context %s type %s", modem->path,
				context_path, context_type);
		} else if (g_str_equal(key, "Settings")) {
			DBG("%s Settings", modem->path);

			extract_ipv4_settings(&value, context);
		} else if (g_str_equal(key, "IPv6.Settings")) {
			DBG("%s IPv6.Settings", modem->path);

			extract_ipv6_settings(&value, context);
		} else if (g_str_equal(key, "Active")) {
			dbus_message_iter_get_basic(&value, &active);

			DBG("%s Active %d", modem->path, active);
		} else if (g_str_equal(key, "AccessPointName")) {
			const char *apn;

			dbus_message_iter_get_basic(&value, &apn);
			if (apn && strlen(apn) > 0)
				modem->valid_apn = true;
			else
				modem->valid_apn = false;

			DBG("%s AccessPointName '%s'", modem->path, apn);
		}  else if (g_str_equal(key, "Protocol") &&
			dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING ) {

			dbus_message_iter_get_basic(&value, &ip_protocol);

			DBG("%s Protocol %s", modem->path, ip_protocol);
		}

		dbus_message_iter_next(dict);
	}

	if (g_strcmp0(context_type, "internet") != 0) {
		network_context_free(context);
		return -EINVAL;
	}

	if (ip_protocol)
		set_context_ipconfig(context, ip_protocol);

	modem->context = context;
	modem->active = active;

	g_hash_table_replace(context_hash, g_strdup(context_path), modem);

	if (modem->valid_apn && modem->attached &&
			has_interface(modem->interfaces,
				OFONO_API_NETREG)) {
		add_network(modem);
	}

	return 0;
}

static void remove_cm_context(struct modem_data *modem,
				const char *context_path)
{
	if (!modem->context)
		return;

	if (modem->network)
		remove_network(modem);

	g_hash_table_remove(context_hash, context_path);

	network_context_free(modem->context);
	modem->context = NULL;

	modem->valid_apn = false;

	if (modem->network)
		remove_network(modem);
}

static gboolean context_changed(DBusConnection *conn,
				DBusMessage *message,
				void *user_data)
{
	const char *context_path = dbus_message_get_path(message);
	struct modem_data *modem = NULL;
	DBusMessageIter iter, value;
	const char *key;

	DBG("context_path %s", context_path);

	modem = g_hash_table_lookup(context_hash, context_path);
	if (!modem)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	/*
	 * oFono guarantees the ordering of Settings and
	 * Active. Settings will always be send before Active = True.
	 * That means we don't have to order here.
	 */
	if (g_str_equal(key, "Settings")) {
		DBG("%s Settings", modem->path);

		extract_ipv4_settings(&value, modem->context);
	} else if (g_str_equal(key, "IPv6.Settings")) {
		DBG("%s IPv6.Settings", modem->path);

		extract_ipv6_settings(&value, modem->context);
	} else if (g_str_equal(key, "Active")) {
		dbus_bool_t active;

		dbus_message_iter_get_basic(&value, &active);
		modem->active = active;

		DBG("%s Active %d", modem->path, modem->active);

		if (modem->active)
			set_connected(modem);
		else
			set_disconnected(modem);
	} else if (g_str_equal(key, "AccessPointName")) {
		const char *apn;

		dbus_message_iter_get_basic(&value, &apn);

		DBG("%s AccessPointName %s", modem->path, apn);

		if (apn && strlen(apn) > 0) {
			modem->valid_apn = true;

			if (modem->network)
				return TRUE;

			if (!modem->attached)
				return TRUE;

			if (!has_interface(modem->interfaces,
						OFONO_API_NETREG))
				return TRUE;

			add_network(modem);

			if (modem->active)
				set_connected(modem);
		} else {
			modem->valid_apn = false;

			if (!modem->network)
				return TRUE;

			remove_network(modem);
		}

	} else if (g_str_equal(key, "Protocol") &&
		dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING ) {
		const char *ip_protocol;

		dbus_message_iter_get_basic(&value, &ip_protocol);

		set_context_ipconfig(modem->context, ip_protocol);
	}

	return TRUE;
}

static void cm_get_contexts_reply(DBusPendingCall *call, void *user_data)
{
	struct modem_data *modem = user_data;
	DBusMessageIter array, dict, entry, value;
	DBusMessage *reply;
	DBusError error;

	DBG("%s", modem->path);

	modem->call_get_contexts = NULL;

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (!dbus_message_iter_init(reply, &array))
		goto done;

	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
		goto done;

	dbus_message_iter_recurse(&array, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
		const char *context_path;

		dbus_message_iter_recurse(&dict, &entry);
		dbus_message_iter_get_basic(&entry, &context_path);

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

		if (add_cm_context(modem, context_path, &value) == 0)
			break;

		dbus_message_iter_next(&dict);
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static int cm_get_contexts(struct modem_data *modem)
{
	DBusMessage *message;

	DBG("%s", modem->path);

	if (modem->call_get_contexts)
		return -EBUSY;

	message = dbus_message_new_method_call(OFONO_SERVICE, modem->path,
					OFONO_CM_INTERFACE, GET_CONTEXTS);
	if (!message)
		return -ENOMEM;

	if (!dbus_connection_send_with_reply(connection, message,
					&modem->call_get_contexts, TIMEOUT)) {
		connman_error("Failed to call GetContexts()");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!modem->call_get_contexts) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	dbus_pending_call_set_notify(modem->call_get_contexts,
					cm_get_contexts_reply,
					modem, NULL);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static gboolean cm_context_added(DBusConnection *conn,
					DBusMessage *message,
					void *user_data)
{
	const char *path = dbus_message_get_path(message);
	char *context_path;
	struct modem_data *modem;
	DBusMessageIter iter, properties;

	DBG("%s", path);

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &context_path);

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

	if (add_cm_context(modem, context_path, &properties) != 0)
		return TRUE;

	return TRUE;
}

static gboolean cm_context_removed(DBusConnection *conn,
					DBusMessage *message,
					void *user_data)
{
	const char *path = dbus_message_get_path(message);
	const char *context_path;
	struct modem_data *modem;
	DBusMessageIter iter;

	DBG("context path %s", path);

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &context_path);

	modem = g_hash_table_lookup(context_hash, context_path);
	if (!modem)
		return TRUE;

	remove_cm_context(modem, context_path);

	return TRUE;
}

static void netreg_update_name(struct modem_data *modem,
				DBusMessageIter* value)
{
	char *name;

	dbus_message_iter_get_basic(value, &name);

	DBG("%s Name %s", modem->path, name);

	g_free(modem->name);
	modem->name = g_strdup(name);

	if (!modem->network)
		return;

	connman_network_set_name(modem->network, modem->name);
	connman_network_update(modem->network);
}

static void netreg_update_strength(struct modem_data *modem,
					DBusMessageIter *value)
{
	dbus_message_iter_get_basic(value, &modem->strength);

	DBG("%s Strength %d", modem->path, modem->strength);

	if (!modem->network)
		return;

	/*
	 * GSM:
	 * We don't have 2 signal notifications we always report the strength
	 * signal. data_strength is always equal to 0.
	 *
	 * CDMA:
	 * In the case we have a data_strength signal (from 1xEVDO network)
	 * we don't need to update the value with strength signal (from 1xCDMA)
	 * because the modem is registered to 1xEVDO network for data call.
	 * In case we have no data_strength signal (not registered to 1xEVDO
	 * network), we must report the strength signal (registered to 1xCDMA
	 * network e.g slow mode).
	 */
	if (modem->data_strength != 0)
		return;

	connman_network_set_strength(modem->network, modem->strength);
	connman_network_update(modem->network);
}

/* Retrieve 1xEVDO Data Strength signal */
static void netreg_update_datastrength(struct modem_data *modem,
					DBusMessageIter *value)
{
	dbus_message_iter_get_basic(value, &modem->data_strength);

	DBG("%s Data Strength %d", modem->path, modem->data_strength);

	if (!modem->network)
		return;

	/*
	 * CDMA modem is not registered to 1xEVDO network, let
	 * update_signal_strength() reporting the value on the Strength signal
	 * notification.
	 */
	if (modem->data_strength == 0)
		return;

	connman_network_set_strength(modem->network, modem->data_strength);
	connman_network_update(modem->network);
}

static void netreg_update_status(struct modem_data *modem,
					DBusMessageIter *value)
{
	char *status;
	bool roaming;

	dbus_message_iter_get_basic(value, &status);

	roaming = g_str_equal(status, "roaming");
	modem->registered = roaming || g_str_equal(status, "registered");

	if (roaming == modem->roaming)
		return;

	modem->roaming = roaming;

	if (!modem->network)
		return;

	connman_network_set_bool(modem->network,
				"Roaming", modem->roaming);
	connman_network_update(modem->network);
}

static void netreg_update_regdom(struct modem_data *modem,
				DBusMessageIter *value)
{
	char *mobile_country_code;
	char *alpha2;
	int mcc;

	dbus_message_iter_get_basic(value, &mobile_country_code);

	DBG("%s MobileContryCode %s", modem->path, mobile_country_code);


	mcc = atoi(mobile_country_code);
	if (mcc > 799 || mcc < 200)
		return;

	alpha2 = mcc_country_codes[mcc - 200];
	if (alpha2)
		connman_technology_set_regdom(alpha2);
}

static gboolean netreg_changed(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->ignore)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "Name"))
		netreg_update_name(modem, &value);
	else if (g_str_equal(key, "Strength"))
		netreg_update_strength(modem, &value);
	else if (g_str_equal(key, "Status"))
		netreg_update_status(modem, &value);
	else if (g_str_equal(key, "MobileCountryCode"))
		netreg_update_regdom(modem, &value);

	return TRUE;
}

static void netreg_properties_reply(struct modem_data *modem,
					DBusMessageIter *dict)
{
	DBG("%s", modem->path);

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

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

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

		if (g_str_equal(key, "Name"))
			netreg_update_name(modem, &value);
		else if (g_str_equal(key, "Strength"))
			netreg_update_strength(modem, &value);
		else if (g_str_equal(key, "Status"))
			netreg_update_status(modem, &value);
		else if (g_str_equal(key, "MobileCountryCode"))
			netreg_update_regdom(modem, &value);

		dbus_message_iter_next(dict);
	}

	if (!modem->context) {
		/*
		 * netgreg_get_properties() was issued after we got
		 * cm_get_contexts_reply() where we create the
		 * context. Though before we got the
		 * netreg_properties_reply the context was removed
		 * again. Therefore we have to skip the network
		 * creation.
		 */
		return;
	}

	if (modem->valid_apn)
		add_network(modem);

	if (modem->active)
		set_connected(modem);
}

static int netreg_get_properties(struct modem_data *modem)
{
	return get_properties(modem->path, OFONO_NETREG_INTERFACE,
			netreg_properties_reply, modem);
}

static void add_cdma_network(struct modem_data *modem)
{
	/* Be sure that device is created before adding CDMA network */
	if (!modem->device)
		return;

	/*
	 * CDMA modems don't need contexts for data call, however the current
	 * add_network() logic needs one, so we create one to proceed.
	 */
	if (!modem->context)
		modem->context = network_context_alloc(modem->path);

	if (!modem->name)
		modem->name = g_strdup("CDMA Network");

	add_network(modem);

	if (modem->cdma_cm_powered)
		set_connected(modem);
}

static gboolean cdma_netreg_changed(DBusConnection *conn,
					DBusMessage *message,
					void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	DBG("");

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->ignore)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "Name"))
		netreg_update_name(modem, &value);
	else if (g_str_equal(key, "Strength"))
		netreg_update_strength(modem, &value);
	else if (g_str_equal(key, "DataStrength"))
		netreg_update_datastrength(modem, &value);
	else if (g_str_equal(key, "Status"))
		netreg_update_status(modem, &value);

	if (modem->registered)
		add_cdma_network(modem);
	else
		remove_network(modem);

	return TRUE;
}

static void cdma_netreg_properties_reply(struct modem_data *modem,
					DBusMessageIter *dict)
{
	DBG("%s", modem->path);

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

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

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

		if (g_str_equal(key, "Name"))
			netreg_update_name(modem, &value);
		else if (g_str_equal(key, "Strength"))
			netreg_update_strength(modem, &value);
		else if (g_str_equal(key, "DataStrength"))
			netreg_update_datastrength(modem, &value);
		else if (g_str_equal(key, "Status"))
			netreg_update_status(modem, &value);

		dbus_message_iter_next(dict);
	}

	if (modem->registered)
		add_cdma_network(modem);
	else
		remove_network(modem);
}

static int cdma_netreg_get_properties(struct modem_data *modem)
{
	return get_properties(modem->path, OFONO_CDMA_NETREG_INTERFACE,
			cdma_netreg_properties_reply, modem);
}

static void cm_update_attached(struct modem_data *modem,
				DBusMessageIter *value)
{
	dbus_bool_t attached;

	dbus_message_iter_get_basic(value, &attached);
	modem->attached = attached;

	DBG("%s Attached %d", modem->path, modem->attached);

	if (!modem->attached) {
		remove_network(modem);
		return;
	}

	if (!has_interface(modem->interfaces, OFONO_API_NETREG))
		return;

	netreg_get_properties(modem);
}

static void cm_update_powered(struct modem_data *modem,
				DBusMessageIter *value)
{
	dbus_bool_t cm_powered;

	dbus_message_iter_get_basic(value, &cm_powered);
	modem->cm_powered = cm_powered;

	DBG("%s ConnnectionManager Powered %d", modem->path,
		modem->cm_powered);

	if (modem->cm_powered)
		return;

	cm_set_powered(modem, TRUE);
}

static gboolean cm_changed(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->ignore)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "Attached"))
		cm_update_attached(modem, &value);
	else if (g_str_equal(key, "Powered"))
		cm_update_powered(modem, &value);

	return TRUE;
}

static void cdma_cm_update_powered(struct modem_data *modem,
					DBusMessageIter *value)
{
	dbus_bool_t cdma_cm_powered;

	dbus_message_iter_get_basic(value, &cdma_cm_powered);
	modem->cdma_cm_powered = cdma_cm_powered;

	DBG("%s CDMA cm Powered %d", modem->path, modem->cdma_cm_powered);

	if (!modem->network)
		return;

	if (modem->cdma_cm_powered)
		set_connected(modem);
	else
		set_disconnected(modem);
}

static void cdma_cm_update_settings(struct modem_data *modem,
					DBusMessageIter *value)
{
	DBG("%s Settings", modem->path);

	extract_ipv4_settings(value, modem->context);
}

static gboolean cdma_cm_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->online && !modem->network)
		cdma_netreg_get_properties(modem);

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "Powered"))
		cdma_cm_update_powered(modem, &value);
	if (g_str_equal(key, "Settings"))
		cdma_cm_update_settings(modem, &value);

	return TRUE;
}

static void cm_properties_reply(struct modem_data *modem, DBusMessageIter *dict)
{
	DBG("%s", modem->path);

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

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

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

		if (g_str_equal(key, "Attached"))
			cm_update_attached(modem, &value);
		else if (g_str_equal(key, "Powered"))
			cm_update_powered(modem, &value);

		dbus_message_iter_next(dict);
	}
}

static int cm_get_properties(struct modem_data *modem)
{
	return get_properties(modem->path, OFONO_CM_INTERFACE,
				cm_properties_reply, modem);
}

static void cdma_cm_properties_reply(struct modem_data *modem,
					DBusMessageIter *dict)
{
	DBG("%s", modem->path);

	if (modem->online)
		cdma_netreg_get_properties(modem);

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

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

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

		if (g_str_equal(key, "Powered"))
			cdma_cm_update_powered(modem, &value);
		if (g_str_equal(key, "Settings"))
			cdma_cm_update_settings(modem, &value);

		dbus_message_iter_next(dict);
	}
}

static int cdma_cm_get_properties(struct modem_data *modem)
{
	return get_properties(modem->path, OFONO_CDMA_CM_INTERFACE,
				cdma_cm_properties_reply, modem);
}

static void sim_update_imsi(struct modem_data *modem,
				DBusMessageIter *value)
{
	char *imsi;

	dbus_message_iter_get_basic(value, &imsi);

	DBG("%s imsi %s", modem->path, imsi);

	g_free(modem->imsi);
	modem->imsi = g_strdup(imsi);
}

static gboolean sim_changed(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->ignore)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "SubscriberIdentity")) {
		sim_update_imsi(modem, &value);
		/*
		Device identifier cound be "UNKNOWN" before we have
		SIM ID or serial num. So here we update modem device's
		ident sinc we have a new SIM ID.
		*/
		update_device_ident(modem->device, modem);
	}

	return TRUE;
}

static void sim_properties_reply(struct modem_data *modem,
					DBusMessageIter *dict)
{
	DBG("%s", modem->path);

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

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

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

		if (g_str_equal(key, "SubscriberIdentity")) {
			sim_update_imsi(modem, &value);
			/*
			Device identifier cound be "UNKNOWN" before we have
			SIM ID or serial num. So here we update modem device's
			ident sinc we have a new SIM ID.
			*/
			update_device_ident(modem->device, modem);

			if (!modem->online)
				return;

			/*
			 * The modem is already online and we have the CM interface.
			 * There will be no interface update and therefore our
			 * state machine will not go to next step. We have to
			 * trigger it from here.
			 */
			if (has_interface(modem->interfaces, OFONO_API_CM)) {
				cm_get_properties(modem);
				cm_get_contexts(modem);
			}
			return;
		}

		dbus_message_iter_next(dict);
	}
}

static int sim_get_properties(struct modem_data *modem)
{
	return get_properties(modem->path, OFONO_SIM_INTERFACE,
				sim_properties_reply, modem);
}

static bool api_added(uint8_t old_iface, uint8_t new_iface,
				enum ofono_api api)
{
	if (!has_interface(old_iface, api) &&
			has_interface(new_iface, api)) {
		DBG("%s added", api2string(api));
		return true;
	}

	return false;
}

static bool api_removed(uint8_t old_iface, uint8_t new_iface,
				enum ofono_api api)
{
	if (has_interface(old_iface, api) &&
			!has_interface(new_iface, api)) {
		DBG("%s removed", api2string(api));
		return true;
	}

	return false;
}

static void modem_update_interfaces(struct modem_data *modem,
				uint8_t old_ifaces,
				uint8_t new_ifaces)
{
	DBG("%s", modem->path);

	if (api_added(old_ifaces, new_ifaces, OFONO_API_SIM)) {
		if (!modem->imsi &&
				!modem->set_powered) {
			/*
			 * Only use do GetProperties() when
			 * device has not been powered up.
			 */
			sim_get_properties(modem);
		}
	}

	if (api_added(old_ifaces, new_ifaces, OFONO_API_CM)) {
		if (modem->device) {
			cm_get_properties(modem);
			cm_get_contexts(modem);
		}
	}

	if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_CM)) {
		/*
		Device identifier cound be "UNKNOWN" before we have
		SIM ID or serial num. So here we update modem device's
		ident sinc we have a new SIM ID.
		*/
		update_device_ident(modem->device, modem);
		if (modem->registered)
			add_cdma_network(modem);

		if (modem->device)
			cdma_cm_get_properties(modem);
	}

	if (api_added(old_ifaces, new_ifaces, OFONO_API_NETREG)) {
		if (modem->attached)
			netreg_get_properties(modem);
	}

	if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
		cdma_netreg_get_properties(modem);

	if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM)) {
		if (modem->call_get_contexts) {
			DBG("cancelling pending GetContexts call");
			dbus_pending_call_cancel(modem->call_get_contexts);
			dbus_pending_call_unref(modem->call_get_contexts);
			modem->call_get_contexts = NULL;
		}
		if (modem->context) {
			DBG("removing context %s", modem->context->path);
			remove_cm_context(modem, modem->context->path);
		}
	}

	if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_CM))
		remove_cm_context(modem, modem->context->path);

	if (api_removed(old_ifaces, new_ifaces, OFONO_API_NETREG))
		remove_network(modem);

	if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
		remove_network(modem);
}

static gboolean modem_changed(DBusConnection *conn, DBusMessage *message,
				void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct modem_data *modem;
	DBusMessageIter iter, value;
	const char *key;

	modem = g_hash_table_lookup(modem_hash, path);
	if (!modem)
		return TRUE;

	if (modem->ignore)
		return TRUE;

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

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

	if (g_str_equal(key, "Powered")) {
		dbus_bool_t powered;

		dbus_message_iter_get_basic(&value, &powered);
		modem->powered = powered;

		DBG("%s Powered %d", modem->path, modem->powered);

		connman_device_set_powered(modem->device, modem->powered);

	} else if (g_str_equal(key, "Online")) {
		dbus_bool_t online;

		dbus_message_iter_get_basic(&value, &online);
		modem->online = online;

		DBG("%s Online %d", modem->path, modem->online);

		if (!modem->device)
			return TRUE;
	} else if (g_str_equal(key, "Interfaces")) {
		uint8_t interfaces;

		interfaces = extract_interfaces(&value);

		if (interfaces == modem->interfaces)
			return TRUE;

		DBG("%s Interfaces 0x%02x", modem->path, interfaces);

		modem_update_interfaces(modem, modem->interfaces, interfaces);

		modem->interfaces = interfaces;
	} else if (g_str_equal(key, "Serial")) {
		char *serial;

		dbus_message_iter_get_basic(&value, &serial);

		g_free(modem->serial);
		modem->serial = g_strdup(serial);

		DBG("%s Serial %s", modem->path, modem->serial);

		if (has_interface(modem->interfaces,
					 OFONO_API_CDMA_CM)) {
			/*
			Device identifier cound be "UNKNOWN" before we have
			SIM ID or serial num. So here we try to update modem
			device's ident.
			*/
			update_device_ident(modem->device, modem);
			if (modem->registered)
				add_cdma_network(modem);
		}
	}

	return TRUE;
}

static void add_modem(const char *path, DBusMessageIter *prop)
{
	struct modem_data *modem;

	DBG("%s", path);

	modem = g_hash_table_lookup(modem_hash, path);
	if (modem) {
		/*
		 * When oFono powers up we ask for the modems and oFono is
		 * reporting with modem_added signal the modems. Only
		 * handle them once.
		 */
		return;
	}

	modem = g_try_new0(struct modem_data, 1);
	if (!modem)
		return;

	modem->path = g_strdup(path);

	g_hash_table_insert(modem_hash, g_strdup(path), modem);

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

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

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

		if (g_str_equal(key, "Powered")) {
			dbus_bool_t powered;

			dbus_message_iter_get_basic(&value, &powered);
			modem->powered = powered;

			DBG("%s Powered %d", modem->path, modem->powered);
		} else if (g_str_equal(key, "Online")) {
			dbus_bool_t online;

			dbus_message_iter_get_basic(&value, &online);
			modem->online = online;

			DBG("%s Online %d", modem->path, modem->online);
		} else if (g_str_equal(key, "Interfaces")) {
			modem->interfaces = extract_interfaces(&value);

			DBG("%s Interfaces 0x%02x", modem->path,
				modem->interfaces);
		} else if (g_str_equal(key, "Serial")) {
			char *serial;

			dbus_message_iter_get_basic(&value, &serial);
			modem->serial = g_strdup(serial);

			DBG("%s Serial %s", modem->path, modem->serial);
		} else if (g_str_equal(key, "Type")) {
			char *type;

			dbus_message_iter_get_basic(&value, &type);

			DBG("%s Type %s", modem->path, type);
			if (g_strcmp0(type, "hardware") != 0) {
				DBG("%s Ignore this modem", modem->path);
				modem->ignore = true;
			}
		}

		dbus_message_iter_next(prop);
	}

	if (!modem->device)
		create_device(modem);

	if (modem->ignore)
		return;

	modem_update_interfaces(modem, 0, modem->interfaces);
}

static void modem_power_down(gpointer key, gpointer value, gpointer user_data)
{
	struct modem_data *modem = value;

	DBG("%s", modem->path);

	if (modem->ignore)
		return;

	modem_set_powered(modem, FALSE);
}

static void remove_modem(gpointer data)
{
	struct modem_data *modem = data;

	DBG("%s", modem->path);

	if (modem->call_set_property) {
		dbus_pending_call_cancel(modem->call_set_property);
		dbus_pending_call_unref(modem->call_set_property);
		modem->call_set_property = NULL;
	}

	if (modem->call_get_properties) {
		dbus_pending_call_cancel(modem->call_get_properties);
		dbus_pending_call_unref(modem->call_get_properties);
		modem->call_get_properties = NULL;
	}

	if (modem->call_get_contexts) {
		dbus_pending_call_cancel(modem->call_get_contexts);
		dbus_pending_call_unref(modem->call_get_contexts);
		modem->call_get_contexts = NULL;
	}

	if (modem->device)
		destroy_device(modem);

	if (modem->context)
		remove_cm_context(modem, modem->context->path);

	g_free(modem->serial);
	g_free(modem->name);
	g_free(modem->imsi);
	g_free(modem->path);

	g_free(modem);
}

static gboolean modem_added(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	DBusMessageIter iter, properties;
	const char *path;

	DBG("");

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &path);

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

	add_modem(path, &properties);

	return TRUE;
}

static gboolean modem_removed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	DBusMessageIter iter;
	const char *path;

	DBG("");

	if (!dbus_message_iter_init(message, &iter))
		return TRUE;

	dbus_message_iter_get_basic(&iter, &path);

	g_hash_table_remove(modem_hash, path);

	return TRUE;
}

static void manager_get_modems_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;
	DBusMessageIter array, dict;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (!dbus_message_iter_init(reply, &array))
		goto done;

	dbus_message_iter_recurse(&array, &dict);

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

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

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

		add_modem(path, &properties);

		dbus_message_iter_next(&dict);
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}

static int manager_get_modems(void)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("");

	message = dbus_message_new_method_call(OFONO_SERVICE, "/",
					OFONO_MANAGER_INTERFACE, GET_MODEMS);
	if (!message)
		return -ENOMEM;

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to call GetModems()");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	dbus_pending_call_set_notify(call, manager_get_modems_reply,
					NULL, NULL);

	dbus_message_unref(message);

	return -EINPROGRESS;
}

static void ofono_connect(DBusConnection *conn, void *user_data)
{
	DBG("");

	modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
						g_free, remove_modem);
	if (!modem_hash)
		return;

	context_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
						g_free, NULL);
	if (!context_hash) {
		g_hash_table_destroy(modem_hash);
		return;
	}

	manager_get_modems();
}

static void ofono_disconnect(DBusConnection *conn, void *user_data)
{
	DBG("");

	if (!modem_hash || !context_hash)
		return;

	g_hash_table_destroy(modem_hash);
	modem_hash = NULL;

	g_hash_table_destroy(context_hash);
	context_hash = NULL;
}

static int network_probe(struct connman_network *network)
{
	struct modem_data *modem = connman_network_get_data(network);

	DBG("%s network %p", modem->path, network);

	return 0;
}

static void network_remove(struct connman_network *network)
{
	struct modem_data *modem = connman_network_get_data(network);

	DBG("%s network %p", modem->path, network);
}

static int network_connect(struct connman_network *network)
{
	struct modem_data *modem = connman_network_get_data(network);

	DBG("%s network %p", modem->path, network);

	if (has_interface(modem->interfaces, OFONO_API_CM))
		return context_set_active(modem, TRUE);
	else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
		return cdma_cm_set_powered(modem, TRUE);

	connman_error("Connection manager interface not available");

	return -ENOSYS;
}

static int network_disconnect(struct connman_network *network, bool user_initiated)
{
	struct modem_data *modem = connman_network_get_data(network);

	DBG("%s network %p", modem->path, network);

	if (has_interface(modem->interfaces, OFONO_API_CM))
		return context_set_active(modem, FALSE);
	else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
		return cdma_cm_set_powered(modem, FALSE);

	connman_error("Connection manager interface not available");

	return -ENOSYS;
}

static struct connman_network_driver network_driver = {
	.name		= "cellular",
	.type		= CONNMAN_NETWORK_TYPE_CELLULAR,
	.probe		= network_probe,
	.remove		= network_remove,
	.connect	= network_connect,
	.disconnect	= network_disconnect,
};

static int modem_probe(struct connman_device *device)
{
	struct modem_data *modem = connman_device_get_data(device);

	DBG("%s device %p", modem->path, device);

	return 0;
}

static void modem_remove(struct connman_device *device)
{
	struct modem_data *modem = connman_device_get_data(device);

	DBG("%s device %p", modem->path, device);
}

static int modem_enable(struct connman_device *device)
{
	struct modem_data *modem = connman_device_get_data(device);

	DBG("%s device %p", modem->path, device);

	if (modem->powered)
		return 0;

	return modem_set_powered(modem, TRUE);
}

static int modem_disable(struct connman_device *device)
{
	struct modem_data *modem = connman_device_get_data(device);

	DBG("%s device %p", modem->path, device);

	if (!modem->powered)
		return 0;

	return modem_set_powered(modem, FALSE);
}

static struct connman_device_driver modem_driver = {
	.name		= "modem",
	.type		= CONNMAN_DEVICE_TYPE_CELLULAR,
	.probe		= modem_probe,
	.remove		= modem_remove,
	.enable		= modem_enable,
	.disable	= modem_disable,
};

static int tech_probe(struct connman_technology *technology)
{
	return 0;
}

static void tech_remove(struct connman_technology *technology)
{
}

static struct connman_technology_driver tech_driver = {
	.name		= "cellular",
	.type		= CONNMAN_SERVICE_TYPE_CELLULAR,
	.probe		= tech_probe,
	.remove		= tech_remove,
};

static guint watch;
static guint modem_added_watch;
static guint modem_removed_watch;
static guint modem_watch;
static guint cm_watch;
static guint sim_watch;
static guint context_added_watch;
static guint context_removed_watch;
static guint netreg_watch;
static guint context_watch;
static guint cdma_cm_watch;
static guint cdma_netreg_watch;

static int ofono_init(void)
{
	int err;

	DBG("");

	connection = connman_dbus_get_connection();
	if (!connection)
		return -EIO;

	watch = g_dbus_add_service_watch(connection,
					OFONO_SERVICE, ofono_connect,
					ofono_disconnect, NULL, NULL);

	modem_added_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
						NULL, OFONO_MANAGER_INTERFACE,
						MODEM_ADDED,
						modem_added,
						NULL, NULL);

	modem_removed_watch = g_dbus_add_signal_watch(connection,
						OFONO_SERVICE, NULL,
						OFONO_MANAGER_INTERFACE,
						MODEM_REMOVED,
						modem_removed,
						NULL, NULL);

	modem_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
						OFONO_MODEM_INTERFACE,
						PROPERTY_CHANGED,
						modem_changed,
						NULL, NULL);

	cm_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
						OFONO_CM_INTERFACE,
						PROPERTY_CHANGED,
						cm_changed,
						NULL, NULL);

	sim_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
						OFONO_SIM_INTERFACE,
						PROPERTY_CHANGED,
						sim_changed,
						NULL, NULL);

	context_added_watch = g_dbus_add_signal_watch(connection,
						OFONO_SERVICE, NULL,
						OFONO_CM_INTERFACE,
						CONTEXT_ADDED,
						cm_context_added,
						NULL, NULL);

	context_removed_watch = g_dbus_add_signal_watch(connection,
						OFONO_SERVICE, NULL,
						OFONO_CM_INTERFACE,
						CONTEXT_REMOVED,
						cm_context_removed,
						NULL, NULL);

	context_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
						NULL, OFONO_CONTEXT_INTERFACE,
						PROPERTY_CHANGED,
						context_changed,
						NULL, NULL);

	netreg_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
						OFONO_NETREG_INTERFACE,
						PROPERTY_CHANGED,
						netreg_changed,
						NULL, NULL);

	cdma_cm_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
						NULL, OFONO_CDMA_CM_INTERFACE,
						PROPERTY_CHANGED,
						cdma_cm_changed,
						NULL, NULL);

	cdma_netreg_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
						NULL, OFONO_CDMA_NETREG_INTERFACE,
						PROPERTY_CHANGED,
						cdma_netreg_changed,
						NULL, NULL);


	if (watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0 ||
			modem_watch == 0 || cm_watch == 0 || sim_watch == 0 ||
			context_added_watch == 0 ||
			context_removed_watch == 0 ||
			context_watch == 0 || netreg_watch == 0 ||
			cdma_cm_watch == 0 || cdma_netreg_watch == 0) {
		err = -EIO;
		goto remove;
	}

	err = connman_network_driver_register(&network_driver);
	if (err < 0)
		goto remove;

	err = connman_device_driver_register(&modem_driver);
	if (err < 0) {
		connman_network_driver_unregister(&network_driver);
		goto remove;
	}

	err = connman_technology_driver_register(&tech_driver);
	if (err < 0) {
		connman_device_driver_unregister(&modem_driver);
		connman_network_driver_unregister(&network_driver);
		goto remove;
	}

	return 0;

remove:
	g_dbus_remove_watch(connection, cdma_netreg_watch);
	g_dbus_remove_watch(connection, cdma_cm_watch);
	g_dbus_remove_watch(connection, netreg_watch);
	g_dbus_remove_watch(connection, context_watch);
	g_dbus_remove_watch(connection, context_removed_watch);
	g_dbus_remove_watch(connection, context_added_watch);
	g_dbus_remove_watch(connection, sim_watch);
	g_dbus_remove_watch(connection, cm_watch);
	g_dbus_remove_watch(connection, modem_watch);
	g_dbus_remove_watch(connection, modem_removed_watch);
	g_dbus_remove_watch(connection, modem_added_watch);
	g_dbus_remove_watch(connection, watch);
	dbus_connection_unref(connection);

	return err;
}

static void ofono_exit(void)
{
	DBG("");

	if (modem_hash) {
		/*
		 * We should propably wait for the SetProperty() reply
		 * message, because ...
		 */
		g_hash_table_foreach(modem_hash, modem_power_down, NULL);

		/*
		 * ... here we will cancel the call.
		 */
		g_hash_table_destroy(modem_hash);
		modem_hash = NULL;
	}

	if (context_hash) {
		g_hash_table_destroy(context_hash);
		context_hash = NULL;
	}

	connman_technology_driver_unregister(&tech_driver);
	connman_device_driver_unregister(&modem_driver);
	connman_network_driver_unregister(&network_driver);

	g_dbus_remove_watch(connection, cdma_netreg_watch);
	g_dbus_remove_watch(connection, cdma_cm_watch);
	g_dbus_remove_watch(connection, netreg_watch);
	g_dbus_remove_watch(connection, context_watch);
	g_dbus_remove_watch(connection, context_removed_watch);
	g_dbus_remove_watch(connection, context_added_watch);
	g_dbus_remove_watch(connection, sim_watch);
	g_dbus_remove_watch(connection, cm_watch);
	g_dbus_remove_watch(connection, modem_watch);
	g_dbus_remove_watch(connection, modem_added_watch);
	g_dbus_remove_watch(connection, modem_removed_watch);
	g_dbus_remove_watch(connection, watch);

	dbus_connection_unref(connection);
}

CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
		CONNMAN_PLUGIN_PRIORITY_DEFAULT, ofono_init, ofono_exit)
