/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012-2013  Tieto Poland
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <gdbus/gdbus.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/sdp.h>

#include "plugin.h"
#include "log.h"
#include "dbus-common.h"
#include "adapter.h"
#include "device.h"
#include "eir.h"
#include "agent.h"
#include "hcid.h"

#define NEARD_NAME "org.neard"
#define NEARD_PATH "/"
#define NEARD_MANAGER_INTERFACE "org.neard.Manager"
#define AGENT_INTERFACE "org.neard.HandoverAgent"
#define AGENT_PATH "/org/bluez/neard_handover_agent"
#define AGENT_CARRIER_TYPE "bluetooth"
#define ERROR_INTERFACE "org.neard.HandoverAgent.Error"

static guint watcher_id = 0;
static char *neard_service = NULL;
static bool agent_register_postpone = false;

/* For NFC mimetype limits max OOB EIR size */
#define NFC_OOB_EIR_MAX UINT8_MAX

enum cps {
	CPS_ACTIVE,
	CPS_INACTIVE,
	CPS_ACTIVATING,
	CPS_UNKNOWN,
};

struct oob_params {
	bdaddr_t address;
	uint32_t class;
	char *name;
	GSList *services;
	uint8_t *hash;
	uint8_t *randomizer;
	uint8_t *pin;
	int pin_len;
	enum cps power_state;
};

static void free_oob_params(struct oob_params *params)
{
	g_slist_free_full(params->services, g_free);
	g_free(params->name);
	g_free(params->hash);
	g_free(params->randomizer);
	g_free(params->pin);
}

static DBusMessage *error_reply(DBusMessage *msg, int error)
{
	const char *name;

	if (error == EINPROGRESS)
		name = ERROR_INTERFACE ".InProgress";
	else
		name = ERROR_INTERFACE ".Failed";

	return g_dbus_create_error(msg, name , "%s", strerror(error));
}

static void register_agent(bool append_carrier);

static void register_agent_cb(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError err;
	static bool try_fallback = true;

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		if (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) &&
				try_fallback) {
			DBG("Register to neard failed, trying legacy way");

			register_agent(false);
			try_fallback = false;
		} else {
			error("neard manager replied with an error: %s, %s",
							err.name, err.message);

			g_dbus_unregister_interface(btd_get_dbus_connection(),
						AGENT_PATH, AGENT_INTERFACE);
			try_fallback = true;
		}

		dbus_error_free(&err);
		dbus_message_unref(reply);

		return;
	}

	dbus_message_unref(reply);
	neard_service = g_strdup(dbus_message_get_sender(reply));

	try_fallback = true;

	info("Registered as neard handover agent");
}

static void register_agent(bool append_carrier)
{
	DBusMessage *message;
	DBusPendingCall *call;
	const char *path = AGENT_PATH;
	const char *carrier = AGENT_CARRIER_TYPE;

	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
			NEARD_MANAGER_INTERFACE, "RegisterHandoverAgent");
	if (!message) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
							DBUS_TYPE_INVALID);

	if (append_carrier)
		dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
							DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
							message, &call, -1)) {
		dbus_message_unref(message);
		error("D-Bus send failed");
		return;
	}

	dbus_pending_call_set_notify(call, register_agent_cb, NULL, NULL);
	dbus_pending_call_unref(call);

	dbus_message_unref(message);
}

static void unregister_agent(void)
{
	DBusMessage *message;
	const char *path = AGENT_PATH;
	const char *carrier = AGENT_CARRIER_TYPE;

	g_free(neard_service);
	neard_service = NULL;

	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
			NEARD_MANAGER_INTERFACE, "UnregisterHandoverAgent");

	if (!message) {
		error("Couldn't allocate D-Bus message");
		goto unregister;
	}

	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
						DBUS_TYPE_INVALID);

	dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
							DBUS_TYPE_INVALID);

	if (!g_dbus_send_message(btd_get_dbus_connection(), message))
		error("D-Bus send failed");

unregister:
	g_dbus_unregister_interface(btd_get_dbus_connection(), AGENT_PATH,
							AGENT_INTERFACE);
}

static void add_power_state(DBusMessageIter *dict, struct btd_adapter *adapter)
{
	const char *state;

	if (btd_adapter_get_powered(adapter) &&
					btd_adapter_get_connectable(adapter))
		state = "active";
	else
		state = "inactive";

	dict_append_entry(dict, "State", DBUS_TYPE_STRING, &state);
}

static DBusMessage *create_request_oob_reply(struct btd_adapter *adapter,
						const uint8_t *hash,
						const uint8_t *randomizer,
						DBusMessage *msg)
{
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	uint8_t eir[NFC_OOB_EIR_MAX];
	uint8_t *peir = eir;
	int len;

	len = eir_create_oob(adapter_get_address(adapter),
				btd_adapter_get_name(adapter),
				btd_adapter_get_class(adapter), hash,
				randomizer, main_opts.did_vendor,
				main_opts.did_product, main_opts.did_version,
				main_opts.did_source,
				btd_adapter_get_services(adapter), eir);

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

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
				&dict);

	dict_append_array(&dict, "EIR", DBUS_TYPE_BYTE, &peir, len);

	add_power_state(&dict, adapter);

	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}

static void read_local_complete(struct btd_adapter *adapter,
				const uint8_t *hash, const uint8_t *randomizer,
				void *user_data)
{
	DBusMessage *msg = user_data;
	DBusMessage *reply;

	DBG("");

	if (neard_service == NULL) {
		dbus_message_unref(msg);

		if (agent_register_postpone) {
			agent_register_postpone = false;
			register_agent(true);
		}

		return;
	}

	if (hash && randomizer)
		reply = create_request_oob_reply(adapter, hash, randomizer,
									msg);
	else
		reply = error_reply(msg, EIO);

	dbus_message_unref(msg);

	if (!g_dbus_send_message(btd_get_dbus_connection(), reply))
		error("D-Bus send failed");
}

static void bonding_complete(struct btd_adapter *adapter,
					const bdaddr_t *bdaddr, uint8_t status,
					void *user_data)
{
	DBusMessage *msg = user_data;
	DBusMessage *reply;

	DBG("");

	if (neard_service == NULL) {
		dbus_message_unref(msg);

		if (agent_register_postpone) {
			agent_register_postpone = false;
			register_agent(true);
		}

		return;
	}

	if (status)
		reply = error_reply(msg, EIO);
	else
		reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

	dbus_message_unref(msg);

	if (!g_dbus_send_message(btd_get_dbus_connection(), reply))
		error("D-Bus send failed");
}

static int check_device(struct btd_device *device)
{
	if (!device)
		return -ENOENT;

	/* If already paired */
	if (device_is_paired(device)) {
		DBG("already paired");
		return -EALREADY;
	}

	/* Pairing in progress... */
	if (device_is_bonding(device, NULL)) {
		DBG("pairing in progress");
		return -EINPROGRESS;
	}

	return 0;
}

static int process_eir(uint8_t *eir, size_t size, struct oob_params *remote)
{
	struct eir_data eir_data;

	DBG("size %zu", size);

	memset(&eir_data, 0, sizeof(eir_data));

	if (eir_parse_oob(&eir_data, eir, size) < 0)
		return -EINVAL;

	bacpy(&remote->address, &eir_data.addr);

	remote->class = eir_data.class;

	remote->name = eir_data.name;
	eir_data.name = NULL;

	remote->services = eir_data.services;
	eir_data.services = NULL;

	remote->hash = eir_data.hash;
	eir_data.hash = NULL;

	remote->randomizer = eir_data.randomizer;
	eir_data.randomizer = NULL;

	eir_data_free(&eir_data);

	return 0;
}

/*
 * This is (barely documented) Nokia extension format, most work was done by
 * reverse engineering.
 *
 * Binary format varies among different devices, type depends on first byte
 * 0x00 - BT address not reversed, 16 bytes authentication data (all zeros)
 * 0x01 - BT address not reversed, 16 bytes authentication data (4 digit PIN,
 *        padded with zeros)
 * 0x02 - BT address not reversed, 16 bytes authentication data (not sure if
 *        16 digit PIN or link key?, Nokia refers to it as ' Public Key')
 * 0x10 - BT address reversed, no authentication data
 * 0x24 - BT address not reversed, 4 bytes authentication data (4 digit PIN)
 *
 * General structure:
 * 1 byte  - marker
 * 6 bytes - BT address (reversed or not, depends on marker)
 * 3 bytes - Class of Device
 * 0, 4 or 16 bytes - authentication data, interpretation depends on marker
 * 1 bytes - name length
 * N bytes - name
 */

static int process_nokia_long (void *data, size_t size, uint8_t marker,
						struct oob_params *remote)
{
	struct {
		bdaddr_t address;
		uint8_t class[3];
		uint8_t authentication[16];
		uint8_t name_len;
		uint8_t name[0];
	} __attribute__((packed)) *n = data;

	if (size != sizeof(*n) + n->name_len)
		return -EINVAL;

	/* address is not reverted */
	baswap(&remote->address, &n->address);

	remote->class = n->class[0] | (n->class[1] << 8) | (n->class[2] << 16);

	if (n->name_len > 0)
		remote->name = g_strndup((char *)n->name, n->name_len);

	if (marker == 0x01) {
		remote->pin = g_memdup(n->authentication, 4);
		remote->pin_len = 4;
	} else if (marker == 0x02) {
		remote->pin = g_memdup(n->authentication, 16);
		remote->pin_len = 16;
	}

	return 0;
}

static int process_nokia_short (void *data, size_t size,
						struct oob_params *remote)
{
	struct {
		bdaddr_t address;
		uint8_t class[3];
		uint8_t authentication[4];
		uint8_t name_len;
		uint8_t name[0];
	} __attribute__((packed)) *n = data;

	if (size != sizeof(*n) + n->name_len)
		return -EINVAL;

	/* address is not reverted */
	baswap(&remote->address, &n->address);

	remote->class = n->class[0] | (n->class[1] << 8) | (n->class[2] << 16);

	if (n->name_len > 0)
		remote->name = g_strndup((char *)n->name, n->name_len);

	remote->pin = g_memdup(n->authentication, 4);
	remote->pin_len = 4;

	return 0;
}

static int process_nokia_extra_short (void *data, size_t size,
						struct oob_params *remote)
{
	struct {
		bdaddr_t address;
		uint8_t class[3];
		uint8_t name_len;
		uint8_t name[0];
	} __attribute__((packed)) *n = data;

	if (size != sizeof(*n) + n->name_len)
		return -EINVAL;

	bacpy(&remote->address, &n->address);

	remote->class = n->class[0] | (n->class[1] << 8) | (n->class[2] << 16);

	if (n->name_len > 0)
		remote->name = g_strndup((char *)n->name, n->name_len);

	return 0;
}

static int process_nokia_com_bt(uint8_t *data, size_t size,
						struct oob_params *remote)
{
	uint8_t marker;

	marker = *data++;
	size--;

	DBG("marker: 0x%.2x  size: %zu", marker, size);

	switch (marker) {
	case 0x00:
	case 0x01:
	case 0x02:
		return process_nokia_long(data, size, marker, remote);
	case 0x10:
		return process_nokia_extra_short(data, size, remote);
	case 0x24:
		return process_nokia_short(data, size, remote);
	default:
		warn("Not supported Nokia NFC extension (0x%.2x)", marker);
		return -EPROTONOSUPPORT;
	}
}

static enum cps process_state(const char *state)
{
	if (strcasecmp(state, "active") == 0)
		return CPS_ACTIVE;

	if (strcasecmp(state, "activating") == 0)
		return CPS_ACTIVATING;

	if (strcasecmp(state, "inactive") == 0)
		return CPS_INACTIVE;

	return CPS_UNKNOWN;
}

static int process_message(DBusMessage *msg, struct oob_params *remote)
{
	DBusMessageIter iter;
	DBusMessageIter dict;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return -EINVAL;

	/* set CPS to unknown in case State was not provided */
	remote->power_state = CPS_UNKNOWN;

	dbus_message_iter_recurse(&iter, &dict);

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

		dbus_message_iter_recurse(&dict, &entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
			goto error;

		dbus_message_iter_get_basic(&entry, &key);
		dbus_message_iter_next(&entry);

		dbus_message_iter_recurse(&entry, &value);

		if (strcasecmp(key, "EIR") == 0) {
			DBusMessageIter array;
			uint8_t *eir;
			int size;

			/* nokia.com:bt and EIR should not be passed together */
			if (bacmp(&remote->address, BDADDR_ANY) != 0)
				goto error;

			if (dbus_message_iter_get_arg_type(&value) !=
					DBUS_TYPE_ARRAY)
				goto error;

			dbus_message_iter_recurse(&value, &array);
			dbus_message_iter_get_fixed_array(&array, &eir, &size);

			if (process_eir(eir, size, remote) < 0)
				goto error;
		} else if (strcasecmp(key, "nokia.com:bt") == 0) {
			DBusMessageIter array;
			uint8_t *data;
			int size;

			/* nokia.com:bt and EIR should not be passed together */
			if (bacmp(&remote->address, BDADDR_ANY) != 0)
				goto error;

			if (dbus_message_iter_get_arg_type(&value) !=
					DBUS_TYPE_ARRAY)
				goto error;

			dbus_message_iter_recurse(&value, &array);
			dbus_message_iter_get_fixed_array(&array, &data, &size);

			if (process_nokia_com_bt(data, size, remote))
				goto error;
		} else if (strcasecmp(key, "State") == 0) {
			DBusMessageIter array;
			const char *state;

			if (dbus_message_iter_get_arg_type(&value) !=
					DBUS_TYPE_STRING)
				goto error;

			dbus_message_iter_recurse(&value, &array);
			dbus_message_iter_get_basic(&value, &state);

			remote->power_state = process_state(state);
			if (remote->power_state == CPS_UNKNOWN)
				goto error;
		}

		dbus_message_iter_next(&dict);
	}

	/* Check if 'State' was passed along with one of other fields */
	if (remote->power_state != CPS_UNKNOWN
			&& bacmp(&remote->address, BDADDR_ANY) == 0)
		return -EINVAL;

	return 0;

error:
	if (bacmp(&remote->address, BDADDR_ANY) != 0) {
		free_oob_params(remote);
		memset(remote, 0, sizeof(*remote));
	}

	return -EINVAL;
}

static int check_adapter(struct btd_adapter *adapter)
{
	if (!adapter)
		return -ENOENT;

	if (btd_adapter_check_oob_handler(adapter))
		return -EINPROGRESS;

	if (!btd_adapter_ssp_enabled(adapter))
		return -ENOTSUP;

	return 0;
}

static void store_params(struct btd_adapter *adapter, struct btd_device *device,
						struct oob_params *params)
{
	if (params->class != 0)
		device_set_class(device, params->class);

	if (params->name) {
		device_store_cached_name(device, params->name);
		device_set_name(device, params->name);
	}

	/* TODO handle UUIDs? */

	if (params->hash) {
		btd_adapter_add_remote_oob_data(adapter, &params->address,
							params->hash,
							params->randomizer);
	} else if (params->pin_len) {
		/* TODO
		 * Handle PIN, for now only discovery mode and 'common' PINs
		 * that might be provided by agent will work correctly.
		 */
	}
}

static DBusMessage *push_oob(DBusConnection *conn, DBusMessage *msg, void *data)
{
	struct btd_adapter *adapter;
	struct agent *agent;
	struct oob_handler *handler;
	struct oob_params remote;
	struct btd_device *device;
	uint8_t io_cap;
	int err;

	if (neard_service == NULL ||
			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
		return error_reply(msg, EPERM);

	DBG("");

	adapter = btd_adapter_get_default();

	err = check_adapter(adapter);
	if (err < 0)
		return error_reply(msg, -err);

	if (!btd_adapter_get_powered(adapter))
		return error_reply(msg, ENONET);

	agent = adapter_get_agent(adapter);
	if (!agent)
		return error_reply(msg, ENONET);

	io_cap = agent_get_io_capability(agent);
	agent_unref(agent);

	memset(&remote, 0, sizeof(remote));

	err = process_message(msg, &remote);
	if (err < 0)
		return error_reply(msg, -err);

	if (bacmp(&remote.address, BDADDR_ANY) == 0) {
		free_oob_params(&remote);

		return error_reply(msg, EINVAL);
	}

	device = adapter_get_device(adapter, &remote.address, BDADDR_BREDR);

	err = check_device(device);
	if (err < 0) {
		free_oob_params(&remote);

		/* already paired, reply immediately */
		if (err == -EALREADY)
			return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

		return error_reply(msg, -err);
	}

	if (!btd_adapter_get_pairable(adapter)) {
		free_oob_params(&remote);

		return error_reply(msg, ENONET);
	}

	store_params(adapter, device, &remote);

	free_oob_params(&remote);

	err = adapter_create_bonding(adapter, device_get_address(device),
							BDADDR_BREDR, io_cap);
	if (err < 0)
		return error_reply(msg, -err);

	handler = g_new0(struct oob_handler, 1);
	handler->bonding_cb = bonding_complete;
	bacpy(&handler->remote_addr, device_get_address(device));
	handler->user_data = dbus_message_ref(msg);

	btd_adapter_set_oob_handler(adapter, handler);

	return NULL;
}

static DBusMessage *request_oob(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct btd_adapter *adapter;
	struct oob_handler *handler;
	struct oob_params remote;
	struct btd_device *device;
	int err;

	if (neard_service == NULL ||
			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
		return error_reply(msg, EPERM);

	DBG("");

	adapter = btd_adapter_get_default();

	err = check_adapter(adapter);
	if (err < 0)
		return error_reply(msg, -err);

	memset(&remote, 0, sizeof(remote));

	err = process_message(msg, &remote);
	if (err < 0)
		return error_reply(msg, -err);

	if (bacmp(&remote.address, BDADDR_ANY) == 0)
		goto read_local;

	device = adapter_get_device(adapter, &remote.address, BDADDR_BREDR);

	err = check_device(device);
	if (err < 0) {
		free_oob_params(&remote);

		if (err == -EALREADY)
			return create_request_oob_reply(adapter, NULL, NULL,
									msg);

		return error_reply(msg, -err);
	}

	if (!btd_adapter_get_pairable(adapter)) {
		free_oob_params(&remote);

		return error_reply(msg, ENONET);
	}

	store_params(adapter, device, &remote);

	if (!remote.hash || !btd_adapter_get_powered(adapter)) {
		free_oob_params(&remote);
		return create_request_oob_reply(adapter, NULL, NULL, msg);
	}

read_local:
	free_oob_params(&remote);

	if (!btd_adapter_get_powered(adapter))
		return create_request_oob_reply(adapter, NULL, NULL, msg);

	err = btd_adapter_read_local_oob_data(adapter);
	if (err < 0)
		return error_reply(msg, -err);

	handler = g_new0(struct oob_handler, 1);
	handler->read_local_cb = read_local_complete;
	handler->user_data = dbus_message_ref(msg);

	btd_adapter_set_oob_handler(adapter, handler);

	return NULL;
}

static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
							void *user_data)
{
	if (neard_service == NULL ||
			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
		return error_reply(msg, EPERM);

	DBG("");

	g_free(neard_service);
	neard_service = NULL;

	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static const GDBusMethodTable neard_methods[] = {
	{ GDBUS_ASYNC_METHOD("RequestOOB",
			GDBUS_ARGS({ "data", "a{sv}" }),
			GDBUS_ARGS({ "data", "a{sv}" }), request_oob) },
	{ GDBUS_ASYNC_METHOD("PushOOB",
			GDBUS_ARGS({ "data", "a{sv}"}), NULL, push_oob) },
	{ GDBUS_METHOD("Release", NULL, NULL, release) },
	{ }
};

static void neard_appeared(DBusConnection *conn, void *user_data)
{
	struct btd_adapter *adapter;

	DBG("");

	if (!g_dbus_register_interface(conn, AGENT_PATH, AGENT_INTERFACE,
						neard_methods,
						NULL, NULL, NULL, NULL)) {
		error("neard interface init failed on path " AGENT_PATH);
		return;
	}

	/*
	 * If there is pending action ongoing when neard appeared, possibly
	 * due to neard crash or release before action was completed, postpone
	 * register until action is finished.
	 */
	adapter = btd_adapter_get_default();

	if (adapter && btd_adapter_check_oob_handler(adapter))
		agent_register_postpone = true;
	else
		register_agent(true);
}

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

	/* neard existed without unregistering agent */
	if (neard_service != NULL) {
		g_free(neard_service);
		neard_service = NULL;

		g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
	}
}

static int neard_init(void)
{
	DBG("Setup neard plugin");

	watcher_id = g_dbus_add_service_watch(btd_get_dbus_connection(),
						NEARD_NAME, neard_appeared,
						neard_vanished, NULL, NULL);
	if (watcher_id == 0)
		return -ENOMEM;

	return 0;
}

static void neard_exit(void)
{
	DBG("Cleanup neard plugin");

	g_dbus_remove_watch(btd_get_dbus_connection(), watcher_id);
	watcher_id = 0;

	if (neard_service != NULL)
		unregister_agent();
}

BLUETOOTH_PLUGIN_DEFINE(neard, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
						neard_init, neard_exit)
