/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2009  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 <net/if.h>

#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP	0x10000
#endif

#include <glib.h>

#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/device.h>
#include <connman/inet.h>
#include <connman/rtnl.h>
#include <connman/log.h>

#define	_DBG_ETHERNET(fmt, arg...)	DBG(DBG_ETHERNET, fmt, ## arg)

struct ethernet_data {
	struct connman_rtnl rtnl;
	unsigned flags;
	unsigned int watch;
};

static void ethernet_newlink(void *user_data, int index, unsigned short type,
    const char *ifname, unsigned flags, int change)
{
	struct connman_device *device = user_data;
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("ifname %s index %d flags %d change %d", ifname,
	    index, flags, change);

	if ((ethernet->flags & IFF_UP) != (flags & IFF_UP)) {
		if (flags & IFF_UP) {
			_DBG_ETHERNET("power on");
			connman_device_set_powered(device, TRUE);
		} else {
			_DBG_ETHERNET("power off");
			connman_device_set_powered(device, FALSE);
		}
	}

	if ((ethernet->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
		if (flags & IFF_LOWER_UP) {
			_DBG_ETHERNET("carrier on");
			connman_device_set_carrier(device, TRUE);
		} else {
			_DBG_ETHERNET("carrier off");
			connman_device_set_carrier(device, FALSE);
		}
	}

	ethernet->flags = flags;
}

static int ethernet_probe(struct connman_device *device)
{
	struct ethernet_data *ethernet;

	_DBG_ETHERNET("device %p", device);

	ethernet = g_try_new0(struct ethernet_data, 1);
	if (ethernet == NULL)
		return -ENOMEM;

	connman_device_set_data(device, ethernet);

	ethernet->flags = 0;

	RTNL_INIT(&ethernet->rtnl,
	     connman_device_get_interface(device),	/* name */
	     CONNMAN_RTNL_PRIORITY_DEFAULT,		/* priority */
	     connman_device_get_index(device),		/* device index */
	     device);					/* private */
	ethernet->rtnl.newlink = ethernet_newlink;

	connman_rtnl_register(&ethernet->rtnl);

	return 0;
}

static void ethernet_remove(struct connman_device *device)
{
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("device %p", device);

	connman_device_set_data(device, NULL);

	connman_rtnl_unregister(&ethernet->rtnl);

	g_free(ethernet);
}

static int ethernet_enable(struct connman_device *device)
{
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("device %p", device);

	return connman_inet_ifup(ethernet->rtnl.index);
}

static int ethernet_disable(struct connman_device *device)
{
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("device %p", device);

	return connman_inet_ifdown(ethernet->rtnl.index);
}

static int ethernet_connect(struct connman_device *device)
{
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("device %p", device);

	if (!(ethernet->flags & IFF_LOWER_UP))
		return -ENOTCONN;

	return connman_device_set_connected(device, TRUE);
}

static int ethernet_disconnect(struct connman_device *device)
{
	struct ethernet_data *ethernet = connman_device_get_data(device);

	_DBG_ETHERNET("device %p", device);

	if (!(ethernet->flags & IFF_LOWER_UP))
		return -ENOTCONN;

	return connman_device_set_connected(device, FALSE);
}

static struct connman_device_driver ethernet_driver = {
	.name		= "ethernet",
	.type		= CONNMAN_DEVICE_TYPE_ETHERNET,
	.probe		= ethernet_probe,
	.remove		= ethernet_remove,
	.enable		= ethernet_enable,
	.disable	= ethernet_disable,
	.connect	= ethernet_connect,
	.disconnect	= ethernet_disconnect,
};

static int ethernet_init(void)
{
	return connman_device_driver_register(&ethernet_driver);
}

static void ethernet_exit(void)
{
	connman_device_driver_unregister(&ethernet_driver);
}

CONNMAN_PLUGIN_DEFINE(ethernet, "Ethernet interface plugin", VERSION,
		CONNMAN_PLUGIN_PRIORITY_DEFAULT, ethernet_init, ethernet_exit)
