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