/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2014  Intel Corporation. All rights reserved.
 *
 *  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 <ctype.h>
#include <gdbus.h>
#include <gdhcp/gdhcp.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>

#include <connman/agent.h>

#include "connman.h"

static DBusConnection *connection = NULL;

static GHashTable *peers_table = NULL;

static struct connman_peer_driver *peer_driver;

struct _peers_notify {
	int id;
	GHashTable *add;
	GHashTable *remove;
} *peers_notify;

struct _peer_service {
	enum connman_peer_service_type type;
	unsigned char *data;
	int length;
};

struct connman_peer {
	int refcount;
	struct connman_device *device;
	struct connman_device *sub_device;
	unsigned char *iface_address[ETH_ALEN];
	char *identifier;
	char *name;
	char *path;
	enum connman_peer_state state;
	struct connman_ipconfig *ipconfig;
	DBusMessage *pending;
	bool registered;
	bool connection_master;
	struct connman_ippool *ip_pool;
	GDHCPServer *dhcp_server;
	uint32_t lease_ip;
	GSList *services;
};

static void settings_changed(struct connman_peer *peer);

static void stop_dhcp_server(struct connman_peer *peer)
{
	DBG("");

	if (peer->dhcp_server)
		g_dhcp_server_unref(peer->dhcp_server);

	peer->dhcp_server = NULL;

	if (peer->ip_pool)
		__connman_ippool_unref(peer->ip_pool);
	peer->ip_pool = NULL;
	peer->lease_ip = 0;
}

static void dhcp_server_debug(const char *str, void *data)
{
	connman_info("%s: %s\n", (const char *) data, str);
}

static void lease_added(unsigned char *mac, uint32_t ip)
{
	GList *list, *start;

	start = list = g_hash_table_get_values(peers_table);
	for (; list; list = list->next) {
		struct connman_peer *temp = list->data;

		if (!memcmp(temp->iface_address, mac, ETH_ALEN)) {
			temp->lease_ip = ip;
			settings_changed(temp);
			break;
		}
	}

	g_list_free(start);
}

static gboolean dhcp_server_started(gpointer data)
{
	struct connman_peer *peer = data;

	connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY);
	connman_peer_unref(peer);

	return FALSE;
}

static int start_dhcp_server(struct connman_peer *peer)
{
	const char *start_ip, *end_ip;
	GDHCPServerError dhcp_error;
	const char *broadcast;
	const char *gateway;
	const char *subnet;
	int prefixlen;
	int index;
	int err;

	DBG("");

	err = -ENOMEM;

	if (peer->sub_device)
		index = connman_device_get_index(peer->sub_device);
	else
		index = connman_device_get_index(peer->device);

	peer->ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);
	if (!peer->ip_pool)
		goto error;

	gateway = __connman_ippool_get_gateway(peer->ip_pool);
	subnet = __connman_ippool_get_subnet_mask(peer->ip_pool);
	broadcast = __connman_ippool_get_broadcast(peer->ip_pool);
	start_ip = __connman_ippool_get_start_ip(peer->ip_pool);
	end_ip = __connman_ippool_get_end_ip(peer->ip_pool);

	prefixlen = connman_ipaddress_calc_netmask_len(subnet);

	err = __connman_inet_modify_address(RTM_NEWADDR,
				NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
				gateway, NULL, prefixlen, broadcast);
	if (err < 0)
		goto error;

	peer->dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &dhcp_error);
	if (!peer->dhcp_server)
		goto error;

	g_dhcp_server_set_debug(peer->dhcp_server,
					dhcp_server_debug, "Peer DHCP server");
	g_dhcp_server_set_lease_time(peer->dhcp_server, 3600);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_SUBNET, subnet);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_ROUTER, gateway);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_DNS_SERVER, NULL);
	g_dhcp_server_set_ip_range(peer->dhcp_server, start_ip, end_ip);

	g_dhcp_server_set_lease_added_cb(peer->dhcp_server, lease_added);

	err = g_dhcp_server_start(peer->dhcp_server);
	if (err < 0)
		goto error;

	g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));

	return 0;

error:
	stop_dhcp_server(peer);
	return err;
}

static void reply_pending(struct connman_peer *peer, int error)
{
	if (!peer->pending)
		return;

	connman_dbus_reply_pending(peer->pending, error, NULL);
	peer->pending = NULL;
}

static void peer_free(gpointer data)
{
	struct connman_peer *peer = data;

	reply_pending(peer, ENOENT);

	connman_peer_unregister(peer);

	if (peer->path) {
		g_free(peer->path);
		peer->path = NULL;
	}

	if (peer->ipconfig) {
		__connman_ipconfig_set_ops(peer->ipconfig, NULL);
		__connman_ipconfig_set_data(peer->ipconfig, NULL);
		__connman_ipconfig_unref(peer->ipconfig);
		peer->ipconfig = NULL;
	}

	stop_dhcp_server(peer);

	if (peer->device) {
		connman_device_unref(peer->device);
		peer->device = NULL;
	}

	if (peer->services)
		connman_peer_reset_services(peer);

	g_free(peer->identifier);
	g_free(peer->name);

	g_free(peer);
}

static const char *state2string(enum connman_peer_state state)
{
	switch (state) {
	case CONNMAN_PEER_STATE_UNKNOWN:
		break;
	case CONNMAN_PEER_STATE_IDLE:
		return "idle";
	case CONNMAN_PEER_STATE_ASSOCIATION:
		return "association";
	case CONNMAN_PEER_STATE_CONFIGURATION:
		return "configuration";
	case CONNMAN_PEER_STATE_READY:
		return "ready";
	case CONNMAN_PEER_STATE_DISCONNECT:
		return "disconnect";
	case CONNMAN_PEER_STATE_FAILURE:
		return "failure";
	}

	return NULL;
}

static bool is_connecting(struct connman_peer *peer)
{
	if (peer->state == CONNMAN_PEER_STATE_ASSOCIATION ||
			peer->state == CONNMAN_PEER_STATE_CONFIGURATION ||
			peer->pending)
		return true;

	return false;
}

static bool is_connected(struct connman_peer *peer)
{
	if (peer->state == CONNMAN_PEER_STATE_READY)
		return true;

	return false;
}

static bool allow_property_changed(struct connman_peer *peer)
{
	if (g_hash_table_lookup_extended(peers_notify->add, peer->path,
								NULL, NULL))
		return false;

	return true;
}

static void append_ipv4(DBusMessageIter *iter, void *user_data)
{
	struct connman_peer *peer = user_data;
	char trans[INET_ADDRSTRLEN+1] = {};
	const char *local = "";
	const char *remote = "";
	char *dhcp = NULL;

	if (!is_connected(peer))
		return;

	if (peer->connection_master) {
		struct in_addr addr;

		addr.s_addr = peer->lease_ip;
		inet_ntop(AF_INET, &addr, trans, INET_ADDRSTRLEN);

		local = __connman_ippool_get_gateway(peer->ip_pool);
		remote = trans;
	} else if (peer->ipconfig) {
		local = __connman_ipconfig_get_local(peer->ipconfig);

		remote = __connman_ipconfig_get_gateway(peer->ipconfig);
		if (!remote) {
			remote = dhcp = __connman_dhcp_get_server_address(
							peer->ipconfig);
			if (!dhcp)
				remote = "";
		}
	}

	connman_dbus_dict_append_basic(iter, "Local",
						DBUS_TYPE_STRING, &local);
	connman_dbus_dict_append_basic(iter, "Remote",
						DBUS_TYPE_STRING, &remote);
	if (dhcp)
		g_free(dhcp);
}

static void append_peer_service(DBusMessageIter *iter,
					struct _peer_service *service)
{
	DBusMessageIter dict;

	connman_dbus_dict_open(iter, &dict);

	switch (service->type) {
	case CONNMAN_PEER_SERVICE_UNKNOWN:
		/* Should never happen */
		break;
	case CONNMAN_PEER_SERVICE_WIFI_DISPLAY:
		connman_dbus_dict_append_fixed_array(&dict,
				"WiFiDisplayIEs", DBUS_TYPE_BYTE,
				&service->data, service->length);
		break;
	}

	connman_dbus_dict_close(iter, &dict);
}

static void append_peer_services(DBusMessageIter *iter, void *user_data)
{
	struct connman_peer *peer = user_data;
	DBusMessageIter container;
	GSList *list;

	dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
							NULL, &container);

	if (!peer->services) {
		DBusMessageIter dict;

		connman_dbus_dict_open(&container, &dict);
		connman_dbus_dict_close(&container, &dict);
	} else {
		for (list = peer->services; list; list = list->next)
			append_peer_service(&container, list->data);
	}

	dbus_message_iter_close_container(iter, &container);
}

static void append_properties(DBusMessageIter *iter, struct connman_peer *peer)
{
	const char *state = state2string(peer->state);
	DBusMessageIter dict;

	connman_dbus_dict_open(iter, &dict);

	connman_dbus_dict_append_basic(&dict, "State",
					DBUS_TYPE_STRING, &state);
	connman_dbus_dict_append_basic(&dict, "Name",
					DBUS_TYPE_STRING, &peer->name);
	connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4, peer);
	connman_dbus_dict_append_array(&dict, "Services",
					DBUS_TYPE_DICT_ENTRY,
					append_peer_services, peer);
	connman_dbus_dict_close(iter, &dict);
}

static void settings_changed(struct connman_peer *peer)
{
	if (!allow_property_changed(peer))
		return;

	connman_dbus_property_changed_dict(peer->path,
					CONNMAN_PEER_INTERFACE, "IPv4",
					append_ipv4, peer);
}

static DBusMessage *get_peer_properties(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct connman_peer *peer = data;
	DBusMessageIter dict;
	DBusMessage *reply;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	dbus_message_iter_init_append(reply, &dict);
	append_properties(&dict, peer);

	return reply;
}

static void append_peer_struct(gpointer key, gpointer value,
						gpointer user_data)
{
	DBusMessageIter *array = user_data;
	struct connman_peer *peer = value;
	DBusMessageIter entry;

	dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
							NULL, &entry);
	dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
							&peer->path);
	append_properties(&entry, peer);
	dbus_message_iter_close_container(array, &entry);
}

static void state_changed(struct connman_peer *peer)
{
	const char *state;

	state = state2string(peer->state);
	if (!state || !allow_property_changed(peer))
		return;

	connman_dbus_property_changed_basic(peer->path,
					 CONNMAN_PEER_INTERFACE, "State",
					 DBUS_TYPE_STRING, &state);
}

static void append_existing_and_new_peers(gpointer key,
					gpointer value, gpointer user_data)
{
	struct connman_peer *peer = value;
	DBusMessageIter *iter = user_data;
	DBusMessageIter entry, dict;

	if (!peer || !peer->registered)
		return;

	if (g_hash_table_lookup(peers_notify->add, peer->path)) {
		DBG("new %s", peer->path);

		append_peer_struct(key, peer, iter);
		g_hash_table_remove(peers_notify->add, peer->path);
	} else if (!g_hash_table_lookup(peers_notify->remove, peer->path)) {
		DBG("existing %s", peer->path);

		dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
								NULL, &entry);
		dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
								&peer->path);
		connman_dbus_dict_open(&entry, &dict);
		connman_dbus_dict_close(&entry, &dict);

		dbus_message_iter_close_container(iter, &entry);
	}
}

static void peer_append_all(DBusMessageIter *iter, void *user_data)
{
	g_hash_table_foreach(peers_table, append_existing_and_new_peers, iter);
}

static void append_removed(gpointer key, gpointer value, gpointer user_data)
{
	DBusMessageIter *iter = user_data;
	char *objpath = key;

	DBG("removed %s", objpath);
	dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
}

static void peer_append_removed(DBusMessageIter *iter, void *user_data)
{
	g_hash_table_foreach(peers_notify->remove, append_removed, iter);
}

static gboolean peer_send_changed(gpointer data)
{
	DBusMessage *signal;

	DBG("");

	peers_notify->id = 0;

	signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
				CONNMAN_MANAGER_INTERFACE, "PeersChanged");
	if (!signal)
		return FALSE;

	__connman_dbus_append_objpath_dict_array(signal,
						peer_append_all, NULL);
	__connman_dbus_append_objpath_array(signal,
						peer_append_removed, NULL);

	dbus_connection_send(connection, signal, NULL);
	dbus_message_unref(signal);

	g_hash_table_remove_all(peers_notify->remove);
	g_hash_table_remove_all(peers_notify->add);

	return FALSE;
}

static void peer_schedule_changed(void)
{
	if (peers_notify->id != 0)
		return;

	peers_notify->id = g_timeout_add(100, peer_send_changed, NULL);
}

static void peer_added(struct connman_peer *peer)
{
	DBG("peer %p", peer);

	g_hash_table_remove(peers_notify->remove, peer->path);
	g_hash_table_replace(peers_notify->add, peer->path, peer);

	peer_schedule_changed();
}

static void peer_removed(struct connman_peer *peer)
{
	DBG("peer %p", peer);

	g_hash_table_remove(peers_notify->add, peer->path);
	g_hash_table_replace(peers_notify->remove, g_strdup(peer->path), NULL);

	peer_schedule_changed();
}

static const char *get_dbus_sender(struct connman_peer *peer)
{
	if (!peer->pending)
		return NULL;

	return dbus_message_get_sender(peer->pending);
}

static enum connman_peer_wps_method check_wpspin(struct connman_peer *peer,
							const char *wpspin)
{
	int len, i;

	if (!wpspin)
		return CONNMAN_PEER_WPS_PBC;

	len = strlen(wpspin);
	if (len == 0)
		return CONNMAN_PEER_WPS_PBC;

	if (len != 8)
		return CONNMAN_PEER_WPS_UNKNOWN;
	for (i = 0; i < 8; i++) {
		if (!isdigit((unsigned char) wpspin[i]))
			return CONNMAN_PEER_WPS_UNKNOWN;
	}

	return CONNMAN_PEER_WPS_PIN;
}

static void request_authorization_cb(struct connman_peer *peer,
					bool choice_done, const char *wpspin,
					const char *error, void *user_data)
{
	enum connman_peer_wps_method wps_method;
	int err;

	DBG("RequestInput return, %p", peer);

	if (error) {
		if (g_strcmp0(error,
				"net.connman.Agent.Error.Canceled") == 0 ||
			g_strcmp0(error,
				"net.connman.Agent.Error.Rejected") == 0) {
			err = -EINVAL;
			goto out;
		}
	}

	if (!choice_done || !peer_driver->connect) {
		err = -EINVAL;
		goto out;
	}

	wps_method = check_wpspin(peer, wpspin);

	err = peer_driver->connect(peer, wps_method, wpspin);
	if (err == -EINPROGRESS)
		return;

out:
	reply_pending(peer, EIO);
	connman_peer_set_state(peer, CONNMAN_PEER_STATE_IDLE);
}

static int peer_connect(struct connman_peer *peer)
{
	int err = -ENOTSUP;

	if (peer_driver->connect)
		err = peer_driver->connect(peer,
					CONNMAN_PEER_WPS_UNKNOWN, NULL);

	if (err == -ENOKEY) {
		err = __connman_agent_request_peer_authorization(peer,
						request_authorization_cb, true,
						get_dbus_sender(peer), NULL);
	}

	return err;
}

static int peer_disconnect(struct connman_peer *peer)
{
	int err = -ENOTSUP;

	connman_agent_cancel(peer);
	reply_pending(peer, ECONNABORTED);

	connman_peer_set_state(peer, CONNMAN_PEER_STATE_DISCONNECT);

	if (peer->connection_master)
		stop_dhcp_server(peer);
	else
		__connman_dhcp_stop(peer->ipconfig);

	if (peer_driver->disconnect)
		err = peer_driver->disconnect(peer);

	connman_peer_set_state(peer, CONNMAN_PEER_STATE_IDLE);

	return err;
}

static DBusMessage *connect_peer(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct connman_peer *peer = user_data;
	GList *list, *start;
	int err;

	DBG("peer %p", peer);

	if (peer->pending)
		return __connman_error_in_progress(msg);

	list = g_hash_table_get_values(peers_table);
	start = list;
	for (; list; list = list->next) {
		struct connman_peer *temp = list->data;

		if (temp == peer || temp->device != peer->device)
			continue;

		if (is_connecting(temp) || is_connected(temp)) {
			if (peer_disconnect(temp) == -EINPROGRESS) {
				g_list_free(start);
				return __connman_error_in_progress(msg);
			}
		}
	}

	g_list_free(start);

	peer->pending = dbus_message_ref(msg);

	err = peer_connect(peer);
	if (err == -EINPROGRESS)
		return NULL;

	if (err < 0) {
		dbus_message_unref(peer->pending);
		peer->pending = NULL;

		return __connman_error_failed(msg, -err);
	}

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static DBusMessage *disconnect_peer(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct connman_peer *peer = user_data;
	int err;

	DBG("peer %p", peer);

	err = peer_disconnect(peer);
	if (err < 0 && err != -EINPROGRESS)
		return __connman_error_failed(msg, -err);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

struct connman_peer *connman_peer_create(const char *identifier)
{
	struct connman_peer *peer;

	peer = g_malloc0(sizeof(struct connman_peer));
	peer->identifier = g_strdup(identifier);
	peer->state = CONNMAN_PEER_STATE_IDLE;

	peer->refcount = 1;

	return peer;
}

struct connman_peer *connman_peer_ref_debug(struct connman_peer *peer,
				const char *file, int line, const char *caller)
{
	DBG("%p ref %d by %s:%d:%s()", peer, peer->refcount + 1,
						file, line, caller);

	__sync_fetch_and_add(&peer->refcount, 1);

	return peer;
}

void connman_peer_unref_debug(struct connman_peer *peer,
				const char *file, int line, const char *caller)
{
	DBG("%p ref %d by %s:%d:%s()", peer, peer->refcount - 1,
						file, line, caller);

	if (__sync_fetch_and_sub(&peer->refcount, 1) != 1)
		return;

	if (!peer->registered && !peer->path)
		return peer_free(peer);

	g_hash_table_remove(peers_table, peer->path);
}

const char *connman_peer_get_identifier(struct connman_peer *peer)
{
	if (!peer)
		return NULL;

	return peer->identifier;
}

void connman_peer_set_name(struct connman_peer *peer, const char *name)
{
	g_free(peer->name);
	peer->name = g_strdup(name);
}

void connman_peer_set_iface_address(struct connman_peer *peer,
					const unsigned char *iface_address)
{
	memset(peer->iface_address, 0, ETH_ALEN);
	memcpy(peer->iface_address, iface_address, ETH_ALEN);
}

void connman_peer_set_device(struct connman_peer *peer,
				struct connman_device *device)
{
	if (!peer || !device)
		return;

	peer->device = device;
	connman_device_ref(device);
}

struct connman_device *connman_peer_get_device(struct connman_peer *peer)
{
	if (!peer)
		return NULL;

	return peer->device;
}

void connman_peer_set_sub_device(struct connman_peer *peer,
					struct connman_device *device)
{
	if (!peer || !device || peer->sub_device)
		return;

	peer->sub_device = device;
}

void connman_peer_set_as_master(struct connman_peer *peer, bool master)
{
	if (!peer || !is_connecting(peer))
		return;

	peer->connection_master = master;
}

static void dhcp_callback(struct connman_ipconfig *ipconfig,
			struct connman_network *network,
			bool success, gpointer data)
{
	struct connman_peer *peer = data;
	int err;

	if (!success)
		goto error;

	DBG("lease acquired for ipconfig %p", ipconfig);

	err = __connman_ipconfig_address_add(ipconfig);
	if (err < 0)
		goto error;

	return;

error:
	__connman_ipconfig_address_remove(ipconfig);
	connman_peer_set_state(peer, CONNMAN_PEER_STATE_FAILURE);
}

static int start_dhcp_client(struct connman_peer *peer)
{
	if (peer->sub_device)
		__connman_ipconfig_set_index(peer->ipconfig,
				connman_device_get_index(peer->sub_device));

	__connman_ipconfig_enable(peer->ipconfig);

	return __connman_dhcp_start(peer->ipconfig, NULL, dhcp_callback, peer);
}

static void report_error_cb(void *user_context, bool retry, void *user_data)
{
	struct connman_peer *peer = user_context;

	if (retry) {
		int err;
		err = peer_connect(peer);

		if (err == 0 || err == -EINPROGRESS)
			return;
	}

	reply_pending(peer, ENOTCONN);

	peer_disconnect(peer);

	if (!peer->connection_master) {
		__connman_dhcp_stop(peer->ipconfig);
		__connman_ipconfig_disable(peer->ipconfig);
	} else
		stop_dhcp_server(peer);

	peer->connection_master = false;
	peer->sub_device = NULL;
}

static int manage_peer_error(struct connman_peer *peer)
{
	int err;

	err = __connman_agent_report_peer_error(peer, peer->path,
					"connect-failed", report_error_cb,
					get_dbus_sender(peer), NULL);
	if (err != -EINPROGRESS) {
		report_error_cb(peer, false, NULL);
		return err;
	}

	return 0;
}

int connman_peer_set_state(struct connman_peer *peer,
					enum connman_peer_state new_state)
{
	enum connman_peer_state old_state = peer->state;
	int err;

	DBG("peer (%s) old state %d new state %d", peer->name,
				old_state, new_state);

	if (old_state == new_state)
		return -EALREADY;

	switch (new_state) {
	case CONNMAN_PEER_STATE_UNKNOWN:
		return -EINVAL;
	case CONNMAN_PEER_STATE_IDLE:
		if (is_connecting(peer) || is_connected(peer))
			return peer_disconnect(peer);
		peer->sub_device = NULL;
		break;
	case CONNMAN_PEER_STATE_ASSOCIATION:
		break;
	case CONNMAN_PEER_STATE_CONFIGURATION:
		if (peer->connection_master)
			err = start_dhcp_server(peer);
		else
			err = start_dhcp_client(peer);
		if (err < 0)
			return connman_peer_set_state(peer,
						CONNMAN_PEER_STATE_FAILURE);
		break;
	case CONNMAN_PEER_STATE_READY:
		reply_pending(peer, 0);
		break;
	case CONNMAN_PEER_STATE_DISCONNECT:
		if (peer->connection_master)
			stop_dhcp_server(peer);
		else
			__connman_dhcp_stop(peer->ipconfig);
		peer->connection_master = false;
		peer->sub_device = NULL;

		break;
	case CONNMAN_PEER_STATE_FAILURE:
		if (manage_peer_error(peer) == 0)
			return 0;
		break;
	};

	peer->state = new_state;
	state_changed(peer);

	if (peer->state == CONNMAN_PEER_STATE_READY ||
				peer->state == CONNMAN_PEER_STATE_DISCONNECT)
		settings_changed(peer);

	return 0;
}

int connman_peer_request_connection(struct connman_peer *peer)
{
	return __connman_agent_request_peer_authorization(peer,
					request_authorization_cb, false,
					NULL, NULL);
}

static void peer_service_free(gpointer data)
{
	struct _peer_service *service = data;

	if (!service)
		return;

	g_free(service->data);
	g_free(service);
}

void connman_peer_reset_services(struct connman_peer *peer)
{
	if (!peer)
		return;

	g_slist_free_full(peer->services, peer_service_free);
	peer->services = NULL;
}

void connman_peer_services_changed(struct connman_peer *peer)
{
	if (!peer || !peer->registered || !allow_property_changed(peer))
		return;

	connman_dbus_property_changed_array(peer->path,
			CONNMAN_PEER_INTERFACE, "Services",
			DBUS_TYPE_DICT_ENTRY, append_peer_services, peer);
}

void connman_peer_add_service(struct connman_peer *peer,
				enum connman_peer_service_type type,
				const unsigned char *data, int data_length)
{
	struct _peer_service *service;

	if (!peer || !data || type == CONNMAN_PEER_SERVICE_UNKNOWN)
		return;

	service = g_malloc0(sizeof(struct _peer_service));
	service->type = type;
	service->data = g_memdup(data, data_length * sizeof(unsigned char));
	service->length = data_length;

	peer->services = g_slist_prepend(peer->services, service);
}

static void peer_up(struct connman_ipconfig *ipconfig, const char *ifname)
{
	DBG("%s up", ifname);
}

static void peer_down(struct connman_ipconfig *ipconfig, const char *ifname)
{
	DBG("%s down", ifname);
}

static void peer_lower_up(struct connman_ipconfig *ipconfig,
							const char *ifname)
{
	DBG("%s lower up", ifname);
}

static void peer_lower_down(struct connman_ipconfig *ipconfig,
							const char *ifname)
{
	struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);

	DBG("%s lower down", ifname);

	__connman_ipconfig_disable(ipconfig);
	connman_peer_set_state(peer, CONNMAN_PEER_STATE_DISCONNECT);
}

static void peer_ip_bound(struct connman_ipconfig *ipconfig,
							const char *ifname)
{
	struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);

	DBG("%s ip bound", ifname);

	if (peer->state == CONNMAN_PEER_STATE_READY)
		settings_changed(peer);
	connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY);
}

static void peer_ip_release(struct connman_ipconfig *ipconfig,
							const char *ifname)
{
	struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);

	DBG("%s ip release", ifname);

	if (peer->state == CONNMAN_PEER_STATE_READY)
		settings_changed(peer);
}

static const struct connman_ipconfig_ops peer_ip_ops = {
	.up		= peer_up,
	.down		= peer_down,
	.lower_up	= peer_lower_up,
	.lower_down	= peer_lower_down,
	.ip_bound	= peer_ip_bound,
	.ip_release	= peer_ip_release,
	.route_set	= NULL,
	.route_unset	= NULL,
};

static struct connman_ipconfig *create_ipconfig(int index, void *user_data)
{
	struct connman_ipconfig *ipconfig;

	ipconfig = __connman_ipconfig_create(index,
						CONNMAN_IPCONFIG_TYPE_IPV4);
	if (!ipconfig)
		return NULL;

	__connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
	__connman_ipconfig_set_data(ipconfig, user_data);
	__connman_ipconfig_set_ops(ipconfig, &peer_ip_ops);

	return ipconfig;
}

static const GDBusMethodTable peer_methods[] = {
	{ GDBUS_METHOD("GetProperties",
			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
			get_peer_properties) },
	{ GDBUS_ASYNC_METHOD("Connect", NULL, NULL, connect_peer) },
	{ GDBUS_METHOD("Disconnect", NULL, NULL, disconnect_peer) },
	{ },
};

static const GDBusSignalTable peer_signals[] = {
	{ GDBUS_SIGNAL("PropertyChanged",
			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
	{ },
};

static char *get_peer_path(struct connman_device *device,
					const char *identifier)
{
	return g_strdup_printf("%s/peer/peer_%s_%s", CONNMAN_PATH,
				connman_device_get_ident(device), identifier);
}

int connman_peer_register(struct connman_peer *peer)
{
	int index;

	DBG("peer %p", peer);

	if (peer->path && peer->registered)
		return -EALREADY;

	index = connman_device_get_index(peer->device);
	peer->ipconfig = create_ipconfig(index, peer);
	if (!peer->ipconfig)
		return -ENOMEM;

	peer->path = get_peer_path(peer->device, peer->identifier);
	DBG("path %s", peer->path);

	g_hash_table_insert(peers_table, peer->path, peer);

	g_dbus_register_interface(connection, peer->path,
					CONNMAN_PEER_INTERFACE,
					peer_methods, peer_signals,
					NULL, peer, NULL);
	peer->registered = true;
	peer_added(peer);

	return 0;
}

void connman_peer_unregister(struct connman_peer *peer)
{
	DBG("peer %p", peer);

	if (!peer->path || !peer->registered)
		return;

	connman_agent_cancel(peer);
	reply_pending(peer, EIO);

	g_dbus_unregister_interface(connection, peer->path,
					CONNMAN_PEER_INTERFACE);
	peer->registered = false;
	peer_removed(peer);
}

struct connman_peer *connman_peer_get(struct connman_device *device,
						const char *identifier)
{
	char *ident = get_peer_path(device, identifier);
	struct connman_peer *peer;

	peer = g_hash_table_lookup(peers_table, ident);
	g_free(ident);

	return peer;
}

int connman_peer_driver_register(struct connman_peer_driver *driver)
{
	if (peer_driver && peer_driver != driver)
		return -EINVAL;

	peer_driver = driver;

	__connman_peer_service_set_driver(driver);

	return 0;
}

void connman_peer_driver_unregister(struct connman_peer_driver *driver)
{
	if (peer_driver != driver)
		return;

	peer_driver = NULL;

	__connman_peer_service_set_driver(NULL);
}

void __connman_peer_list_struct(DBusMessageIter *array)
{
	g_hash_table_foreach(peers_table, append_peer_struct, array);
}

const char *__connman_peer_get_path(struct connman_peer *peer)
{
	if (!peer || !peer->registered)
		return NULL;

	return peer->path;
}

int __connman_peer_init(void)
{
	DBG("");

	connection = connman_dbus_get_connection();

	peers_table = g_hash_table_new_full(g_str_hash, g_str_equal,
							NULL, peer_free);

	peers_notify = g_new0(struct _peers_notify, 1);
	peers_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
	peers_notify->remove = g_hash_table_new_full(g_str_hash, g_str_equal,
								g_free, NULL);
	return 0;
}

void __connman_peer_cleanup(void)
{
	DBG("");

	g_hash_table_destroy(peers_notify->remove);
	g_hash_table_destroy(peers_notify->add);
	g_free(peers_notify);

	g_hash_table_destroy(peers_table);
	peers_table = NULL;
	dbus_connection_unref(connection);
	connection = NULL;
}
