/*
 *
 *  neard - Near Field Communication manager
 *
 *  Copyright (C) 2011  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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <glib.h>

#include <gdbus.h>

#include "near.h"

/* We check for the tag being present every 2 seconds */
#define CHECK_PRESENCE_PERIOD 2

static DBusConnection *connection = NULL;

static GHashTable *adapter_hash;

enum near_adapter_rf_mode {
	NEAR_ADAPTER_RF_MODE_IDLE      = 0,
	NEAR_ADAPTER_RF_MODE_INITIATOR = 1,
	NEAR_ADAPTER_RF_MODE_TARGET    = 2
};

#define NEAR_ADAPTER_MODE_INITIATOR 0x1
#define NEAR_ADAPTER_MODE_TARGET    0x2
#define NEAR_ADAPTER_MODE_DUAL      0x3

struct near_adapter {
	char *path;

	char *name;
	uint32_t idx;
	uint32_t protocols;
	uint32_t poll_mode;
	enum near_adapter_rf_mode rf_mode;

	bool powered;
	bool polling;
	bool constant_poll;
	bool dep_up;

	GHashTable *tags;
	struct near_tag *tag_link;
	int tag_sock;

	GHashTable *devices;
	struct near_device *device_link;
	int device_sock;

	GIOChannel *channel;
	guint watch;
	GList *ioreq_list;

	guint presence_timeout;
	guint dep_timer;
};

struct near_adapter_ioreq {
	uint32_t target_idx;
	near_recv cb;
	unsigned char buf[1024];
	size_t len;
	void *data;
};

/* HACK HACK */
#ifndef AF_NFC
#define AF_NFC 39
#endif

static void free_adapter(gpointer data)
{
	struct near_adapter *adapter = data;

	if (adapter->presence_timeout > 0)
		g_source_remove(adapter->presence_timeout);

	if (adapter->dep_timer > 0)
		g_source_remove(adapter->dep_timer);

	g_free(adapter->name);
	g_free(adapter->path);
	g_hash_table_destroy(adapter->tags);
	g_hash_table_destroy(adapter->devices);
	g_free(adapter);
}

static void free_tag(gpointer data)
{
	struct near_tag *tag = data;

	__near_tag_remove(tag);
}

static void free_device(gpointer data)
{
	struct near_device *device = data;

	__near_device_remove(device);
}

static char *rf_mode_to_string(struct near_adapter *adapter)
{
	switch (adapter->rf_mode) {
	case NEAR_ADAPTER_RF_MODE_IDLE:
		return "Idle";
	case NEAR_ADAPTER_RF_MODE_INITIATOR:
		return "Initiator";
	case NEAR_ADAPTER_RF_MODE_TARGET:
		return "Target";
	}

	return NULL;
}

static void polling_changed(struct near_adapter *adapter)
{
	g_dbus_emit_property_changed(connection, adapter->path,
					NFC_ADAPTER_INTERFACE, "Polling");
}

static void rf_mode_changed(struct near_adapter *adapter)
{
	g_dbus_emit_property_changed(connection, adapter->path,
					NFC_ADAPTER_INTERFACE, "Mode");
}

static int adapter_start_poll(struct near_adapter *adapter)
{
	int err;
	uint32_t im_protos, tm_protos;

	if (g_hash_table_size(adapter->tags) > 0) {
		DBG("Clearing tags");

		g_hash_table_remove_all(adapter->tags);
	}

	if (g_hash_table_size(adapter->devices) > 0) {
		DBG("Clearing devices");

		g_hash_table_remove_all(adapter->devices);
	}

	DBG("Poll mode 0x%x", adapter->poll_mode);

	im_protos = tm_protos = 0;

	if (adapter->poll_mode & NEAR_ADAPTER_MODE_INITIATOR)
		im_protos = adapter->protocols;

	if (adapter->poll_mode & NEAR_ADAPTER_MODE_TARGET)
		tm_protos = adapter->protocols;

	err = __near_netlink_start_poll(adapter->idx, im_protos, tm_protos);
	if (err < 0)
		return err;

	adapter->polling = true;

	polling_changed(adapter);

	return 0;
}

static gboolean property_get_mode(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *user_data)
{
	struct near_adapter *adapter = user_data;
	const char *rf_mode;

	rf_mode = rf_mode_to_string(adapter);
	if (!rf_mode)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &rf_mode);

	return TRUE;
}

static gboolean property_get_polling(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *user_data)
{
	struct near_adapter *adapter = user_data;
	dbus_bool_t val;

	val = adapter->polling;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);

	return TRUE;
}

static gboolean property_get_powered(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *user_data)
{
	struct near_adapter *adapter = user_data;
	dbus_bool_t val;

	val = adapter->powered;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);

	return TRUE;
}

static void set_powered(GDBusPendingPropertySet id, dbus_bool_t powered,
								void *data)
{
	struct near_adapter *adapter = data;
	int err;

	err = __near_netlink_adapter_enable(adapter->idx, powered);
	if (err < 0) {
		if (err == -EALREADY) {
			if (powered)
				g_dbus_pending_property_error(id,
						NFC_ERROR_INTERFACE ".Failed",
						"Device already enabled");
			else
				g_dbus_pending_property_error(id,
						NFC_ERROR_INTERFACE ".Failed",
						"Device already disabled");
		}

		g_dbus_pending_property_error(id,
						NFC_ERROR_INTERFACE ".Failed",
						strerror(err));

		return;
	}

	g_dbus_pending_property_success(id);

	adapter->powered = powered;

	g_dbus_emit_property_changed(connection, adapter->path,
					NFC_ADAPTER_INTERFACE, "Powered");
}

static void property_set_powered(const GDBusPropertyTable *property,
					DBusMessageIter *value,
					GDBusPendingPropertySet id, void *data)
{
	dbus_bool_t powered;

	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
		g_dbus_pending_property_error(id,
					NFC_ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	dbus_message_iter_get_basic(value, &powered);

	set_powered(id, powered, data);
}

static void append_protocols(DBusMessageIter *iter,
					struct near_adapter *adapter)
{
	const char *str;

	DBG("protocols 0x%x", adapter->protocols);

	if (adapter->protocols & NFC_PROTO_FELICA_MASK) {
		str = "Felica";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}

	if (adapter->protocols & NFC_PROTO_MIFARE_MASK) {
		str = "MIFARE";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}

	if (adapter->protocols & NFC_PROTO_JEWEL_MASK) {
		str = "Jewel";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}

	if ((adapter->protocols & NFC_PROTO_ISO14443_MASK) ||
	    (adapter->protocols & NFC_PROTO_ISO14443_B_MASK)) {
		str = "ISO-DEP";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}

	if (adapter->protocols & NFC_PROTO_NFC_DEP_MASK) {
		str = "NFC-DEP";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}

	if (adapter->protocols & NFC_PROTO_ISO15693_MASK) {
		str = "ISO-15693";

		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
	}
}

static gboolean property_get_protocols(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *user_data)
{
	struct near_adapter *adapter = user_data;
	DBusMessageIter dict;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
						DBUS_TYPE_STRING_AS_STRING, &dict);

	append_protocols(&dict, adapter);

	dbus_message_iter_close_container(iter, &dict);

	return TRUE;
}

static DBusMessage *start_poll_loop(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct near_adapter *adapter = data;
	const char *dbus_mode;
	int err;

	DBG("conn %p", conn);

	if (!adapter->powered) {
		near_error("Adapter is down, can not start polling");
		return __near_error_failed(msg, ENODEV);
	}

	dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dbus_mode,
							DBUS_TYPE_INVALID);

	DBG("Mode %s", dbus_mode);

	if (g_strcmp0(dbus_mode, "Initiator") == 0)
		adapter->poll_mode = NEAR_ADAPTER_MODE_INITIATOR;
	else if (g_strcmp0(dbus_mode, "Target") == 0)
		adapter->poll_mode = NEAR_ADAPTER_MODE_TARGET;
	else if (g_strcmp0(dbus_mode, "Dual") == 0)
		adapter->poll_mode = NEAR_ADAPTER_MODE_DUAL;
	else
		adapter->poll_mode = NEAR_ADAPTER_MODE_INITIATOR;

	err = adapter_start_poll(adapter);
	if (err < 0)
		return __near_error_failed(msg, -err);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static DBusMessage *stop_poll_loop(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct near_adapter *adapter = data;
	int err;

	DBG("conn %p", conn);

	if (!adapter->polling)
		return __near_error_not_polling(msg);

	err = __near_netlink_stop_poll(adapter->idx);
	if (err < 0)
		return __near_error_failed(msg, -err);

	adapter->polling = false;

	polling_changed(adapter);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx,
								int status);

static gboolean check_presence(gpointer user_data)
{
	struct near_adapter *adapter = user_data;
	struct near_tag *tag;
	int err;

	DBG("");

	if (!adapter)
		return FALSE;

	tag = adapter->tag_link;
	if (!tag)
		goto out_err;

	err = __near_tag_check_presence(tag, tag_present_cb);
	if (err < 0) {
		DBG("Could not check target presence");
		goto out_err;
	}

	return FALSE;

out_err:
	near_adapter_disconnect(adapter->idx);
	if (adapter->constant_poll)
		adapter_start_poll(adapter);

	return FALSE;
}

static gboolean dep_timer(gpointer user_data)
{
	struct near_adapter *adapter = user_data;

	DBG("");

	if (!adapter)
		return FALSE;

	adapter_start_poll(adapter);

	return FALSE;
}

static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx,
								int status)
{
	struct near_adapter *adapter;

	DBG("");

	adapter = g_hash_table_lookup(adapter_hash,
					GINT_TO_POINTER(adapter_idx));
	if (!adapter)
		return;

	if (status < 0) {
		DBG("Tag is gone");

		near_adapter_disconnect(adapter->idx);
		if (adapter->constant_poll)
			adapter_start_poll(adapter);

		return;
	}

	adapter->presence_timeout =
		g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
					check_presence, adapter);
}

void __near_adapter_start_check_presence(uint32_t adapter_idx,
						uint32_t target_idx)
{
	struct near_adapter *adapter;

	DBG("");

	adapter = g_hash_table_lookup(adapter_hash,
			GINT_TO_POINTER(adapter_idx));
	if (!adapter)
		return;

	adapter->presence_timeout =
			g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
					check_presence, adapter);
}

void __near_adapter_stop_check_presence(uint32_t adapter_idx,
						uint32_t target_idx)
{
	struct near_adapter *adapter;

	DBG("");

	adapter = g_hash_table_lookup(adapter_hash,
			GINT_TO_POINTER(adapter_idx));
	if (!adapter)
		return;

	if (adapter->presence_timeout > 0)
		g_source_remove(adapter->presence_timeout);
}

static const GDBusMethodTable adapter_methods[] = {
	{ GDBUS_METHOD("StartPollLoop", GDBUS_ARGS({"name", "s"}), NULL,
							start_poll_loop) },
	{ GDBUS_METHOD("StopPollLoop", NULL, NULL, stop_poll_loop) },
	{ },
};

static const GDBusPropertyTable adapter_properties[] = {
	{ "Mode", "s", property_get_mode },
	{ "Powered", "b", property_get_powered, property_set_powered },
	{ "Polling", "b", property_get_polling },
	{ "Protocols", "as", property_get_protocols },

	{ }
};

struct near_adapter *__near_adapter_create(uint32_t idx,
		const char *name, uint32_t protocols, bool powered)
{
	struct near_adapter *adapter;
	bool powered_setting;

	adapter = g_try_malloc0(sizeof(struct near_adapter));
	if (!adapter)
		return NULL;

	adapter->name = g_strdup(name);
	if (!adapter->name) {
		g_free(adapter);
		return NULL;
	}

	powered_setting = near_setting_get_bool("DefaultPowered");
	if (powered_setting && !powered &&
	    !__near_netlink_adapter_enable(idx, powered_setting))
			powered = true;

	DBG("Powered %d", powered);

	adapter->idx = idx;
	adapter->protocols = protocols;
	adapter->powered = powered;
	adapter->constant_poll = near_setting_get_bool("ConstantPoll");
	adapter->dep_up = false;
	adapter->tags = g_hash_table_new_full(g_direct_hash, g_direct_equal,
							NULL, free_tag);
	adapter->tag_sock = -1;

	adapter->devices = g_hash_table_new_full(g_direct_hash, g_direct_equal,
							NULL, free_device);
	adapter->device_sock = -1;

	adapter->path = g_strdup_printf("%s/nfc%d", NFC_PATH, idx);

	return adapter;
}

void __near_adapter_destroy(struct near_adapter *adapter)
{
	DBG("");

	free_adapter(adapter);
}

const char *__near_adapter_get_path(struct near_adapter *adapter)
{
	return adapter->path;
}

struct near_adapter *__near_adapter_get(uint32_t idx)
{
	return g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
}

int __near_adapter_set_dep_state(uint32_t idx, bool dep)
{
	struct near_adapter *adapter;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	adapter->dep_up = dep;

	if (!dep && adapter->constant_poll) {
		/*
		 * The immediate polling may fail if the adapter is busy in
		 * that very moment. In this case we need to try polling later
		 * again, so constant polling will work properly.
		 */
		if(adapter_start_poll(adapter) == -EBUSY) {
			near_error("Adapter is busy, retry polling later");
			g_timeout_add_seconds(1, dep_timer, adapter);
		}
	}

	if (!dep) {
		uint32_t target_idx;

		target_idx =  __neard_device_get_idx(adapter->device_link);
		__near_adapter_remove_target(idx, target_idx);
	} else {
		if (adapter->dep_timer > 0)
			g_source_remove(adapter->dep_timer);

		if (!__near_device_register_interface(adapter->device_link))
			return -ENODEV;
	}

	return 0;
}

bool __near_adapter_get_dep_state(uint32_t idx)
{
	struct near_adapter *adapter;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return false;

	return adapter->dep_up;
}

int __near_adapter_add(struct near_adapter *adapter)
{
	uint32_t idx = adapter->idx;

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

	if (g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx)))
		return -EEXIST;

	g_hash_table_insert(adapter_hash, GINT_TO_POINTER(idx), adapter);

	DBG("connection %p", connection);

	g_dbus_register_interface(connection, adapter->path,
					NFC_ADAPTER_INTERFACE,
					adapter_methods, NULL,
					adapter_properties, adapter, NULL);

	return 0;
}

void __near_adapter_remove(struct near_adapter *adapter)
{
	DBG("%s", adapter->path);

	g_dbus_unregister_interface(connection, adapter->path,
						NFC_ADAPTER_INTERFACE);

	g_hash_table_remove(adapter_hash, GINT_TO_POINTER(adapter->idx));
}

static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
{
	struct near_adapter *adapter;

	DBG("status %d", status);

	adapter = g_hash_table_lookup(adapter_hash,
					GINT_TO_POINTER(adapter_idx));
	if (!adapter)
		return;

	if (status < 0) {
		near_adapter_disconnect(adapter->idx);
		if (adapter->constant_poll)
			adapter_start_poll(adapter);

		return;
	}

	adapter->presence_timeout =
		g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
					check_presence, adapter);
}

static void device_read_cb(uint32_t adapter_idx, uint32_t target_idx,
								int status)
{
	struct near_adapter *adapter;

	DBG("status %d", status);

	adapter = g_hash_table_lookup(adapter_hash,
					GINT_TO_POINTER(adapter_idx));
	if (!adapter)
		return;

	if (status < 0) {
		if (adapter->device_link) {
			__near_netlink_dep_link_down(adapter->idx);
			adapter->device_link = NULL;
		}

		if (adapter->constant_poll)
			adapter_start_poll(adapter);

		return;
	}
}

static int adapter_add_tag(struct near_adapter *adapter, uint32_t target_idx,
			uint32_t protocols,
			uint16_t sens_res, uint8_t sel_res,
			uint8_t *nfcid, uint8_t nfcid_len,
			uint8_t iso15693_dsfid,
			uint8_t iso15693_uid_len, uint8_t *iso15693_uid)
{
	struct near_tag *tag;
	uint32_t tag_type;
	int err;

	tag = __near_tag_add(adapter->idx, target_idx, protocols,
				sens_res, sel_res,
				nfcid, nfcid_len,
				iso15693_dsfid, iso15693_uid_len, iso15693_uid);
	if (!tag)
		return -ENODEV;

	g_hash_table_insert(adapter->tags, GINT_TO_POINTER(target_idx), tag);

	tag_type = __near_tag_get_type(tag);

	err = near_adapter_connect(adapter->idx, target_idx, tag_type);
	if (err < 0) {
		near_error("Could not connect");
		return err;
	}

	err = __near_tag_read(tag, tag_read_cb);
	if (err < 0) {
		near_error("Could not read the tag");

		near_adapter_disconnect(adapter->idx);
		__near_adapter_remove_target(adapter->idx, target_idx);
	}

	return err;
}

static int adapter_add_device(struct near_adapter *adapter,
				uint32_t target_idx,
				uint8_t *nfcid, uint8_t nfcid_len)
{
	struct near_device *device;
	int err;

	DBG();

	device = __near_device_add(adapter->idx, target_idx, nfcid, nfcid_len);
	if (!device)
		return -ENODEV;

	g_hash_table_insert(adapter->devices, GINT_TO_POINTER(target_idx),
								device);

	/* For p2p, reading is listening for an incoming connection */
	err = __near_device_listen(device, device_read_cb);
	if (err < 0) {
		near_error("Could not read device");
		return err;
	}

	adapter->device_link = device;

	if (adapter->dep_up) {
		if (!__near_device_register_interface(device))
			return -ENODEV;

		return 0;
	}

	err = __near_netlink_dep_link_up(adapter->idx, target_idx,
					NFC_COMM_ACTIVE, NFC_RF_INITIATOR);

	if (err < 0)
		adapter->device_link = NULL;

	DBG("Starting DEP timer");

	adapter->dep_timer = g_timeout_add_seconds(1, dep_timer, adapter);

	return err;
}

int __near_adapter_add_target(uint32_t idx, uint32_t target_idx,
			uint32_t protocols, uint16_t sens_res, uint8_t sel_res,
			uint8_t *nfcid, uint8_t nfcid_len,
			uint8_t iso15693_dsfid,
			uint8_t iso15693_uid_len, uint8_t *iso15693_uid)
{
	struct near_adapter *adapter;
	int ret;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	adapter->polling = false;
	polling_changed(adapter);

	adapter->rf_mode = NEAR_ADAPTER_RF_MODE_INITIATOR;
	rf_mode_changed(adapter);

	if (protocols & NFC_PROTO_NFC_DEP_MASK)
		ret = adapter_add_device(adapter, target_idx,
						nfcid, nfcid_len);
	else
		ret = adapter_add_tag(adapter, target_idx, protocols,
					sens_res, sel_res, nfcid, nfcid_len,
					iso15693_dsfid,
					iso15693_uid_len, iso15693_uid);

	if (ret < 0 && adapter->constant_poll)
		adapter_start_poll(adapter);

	return ret;
}

int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx)
{
	struct near_adapter *adapter;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	adapter->rf_mode = NEAR_ADAPTER_RF_MODE_IDLE;
	rf_mode_changed(adapter);

	if (g_hash_table_remove(adapter->tags, GINT_TO_POINTER(target_idx)))
		return 0;

	if (g_hash_table_remove(adapter->devices, GINT_TO_POINTER(target_idx)))
		return 0;

	return 0;
}

static gboolean poll_error(gpointer user_data)
{
	struct near_adapter *adapter = user_data;
	bool reset;

	DBG("adapter %d", adapter->idx);

	reset = near_setting_get_bool("ResetOnError");
	if (reset) {
		near_error("Resetting nfc%d", adapter->idx);
		 __near_netlink_adapter_enable(adapter->idx, false);
		 __near_netlink_adapter_enable(adapter->idx, true);
	}

	adapter_start_poll(adapter);

	return FALSE;
}

int __near_adapter_get_targets_done(uint32_t idx)
{
	struct near_adapter *adapter;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	if (g_hash_table_size(adapter->devices) > 0)
		return 0;

	if (g_hash_table_size(adapter->tags) > 0)
		return 0;

	near_error("No targets found - Polling error");

	adapter->polling = false;
	polling_changed(adapter);

	g_idle_add(poll_error, adapter);

	return 0;
}

int __near_adapter_add_device(uint32_t idx, uint8_t *nfcid, uint8_t nfcid_len)
{
	struct near_adapter *adapter;
	int ret;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	adapter->polling = false;
	adapter->dep_up = true;
	adapter->rf_mode = NEAR_ADAPTER_RF_MODE_TARGET;
	polling_changed(adapter);
	rf_mode_changed(adapter);

	ret = adapter_add_device(adapter, 0, nfcid, nfcid_len);
	if (ret < 0)
		return ret;

	return 0;
}

int __near_adapter_remove_device(uint32_t idx)
{
	struct near_adapter *adapter;
	uint32_t device_idx = 0;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	if (!g_hash_table_remove(adapter->devices, GINT_TO_POINTER(device_idx)))
		return 0;

	adapter->rf_mode = NEAR_ADAPTER_RF_MODE_IDLE;
	rf_mode_changed(adapter);

	adapter->dep_up = false;

	if (adapter->constant_poll)
		adapter_start_poll(adapter);

	return 0;
}

static void adapter_flush_rx(struct near_adapter *adapter, int error)
{
	GList *list;

	for (list = adapter->ioreq_list; list; list = list->next) {
		struct near_adapter_ioreq *req = list->data;

		if (!req)
			continue;

		req->cb(NULL, error, req->data);
		g_free(req);
	}

	g_list_free(adapter->ioreq_list);
	adapter->ioreq_list = NULL;
}

static gboolean execute_recv_cb(gpointer user_data)
{
	struct near_adapter_ioreq *req = user_data;

	DBG("data %p", req->data);

	req->cb(req->buf, req->len, req->data);

	g_free(req);

	return FALSE;
}

static gboolean adapter_recv_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	struct near_adapter *adapter = user_data;
	struct near_adapter_ioreq *req;
	GList *first;
	int sk;

	DBG("condition 0x%x", condition);

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		near_error("Error while reading NFC bytes");

		adapter_flush_rx(adapter, -EIO);

		near_adapter_disconnect(adapter->idx);

		return FALSE;
	}

	sk = g_io_channel_unix_get_fd(channel);
	first = g_list_first(adapter->ioreq_list);
	if (!first)
		return TRUE;

	req = first->data;
	req->len = recv(sk, req->buf, sizeof(req->buf), 0);

	adapter->ioreq_list = g_list_remove(adapter->ioreq_list, req);

	g_idle_add(execute_recv_cb, req);

	return TRUE;
}

int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol)
{
	struct near_adapter *adapter;
	struct near_tag *tag;
	struct sockaddr_nfc addr;
	int err, sock;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	if (adapter->tag_sock != -1)
		return -EALREADY;

	tag = g_hash_table_lookup(adapter->tags,
				GINT_TO_POINTER(target_idx));
	if (!tag)
		return -ENOLINK;

	sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW);
	if (sock == -1)
		return sock;

	addr.sa_family = AF_NFC;
	addr.dev_idx = idx;
	addr.target_idx = target_idx;
	addr.nfc_protocol = protocol;

	err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
	if (err) {
		close(sock);
		return err;
	}

	adapter->tag_sock = sock;
	adapter->tag_link = tag;

	if (!adapter->channel)
		adapter->channel = g_io_channel_unix_new(adapter->tag_sock);

	g_io_channel_set_flags(adapter->channel, G_IO_FLAG_NONBLOCK, NULL);
	g_io_channel_set_close_on_unref(adapter->channel, TRUE);

	if (adapter->watch == 0)
		adapter->watch = g_io_add_watch(adapter->channel,
				G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
						adapter_recv_event, adapter);

	return 0;
}

int near_adapter_disconnect(uint32_t idx)
{
	struct near_adapter *adapter;
	uint32_t target_idx;
	uint16_t tag_type;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter)
		return -ENODEV;

	DBG("link %p", adapter->tag_link);

	if (!adapter->tag_link)
		return -ENOLINK;

	tag_type = __near_tag_get_type(adapter->tag_link);
	target_idx = near_tag_get_target_idx(adapter->tag_link);

	DBG("tag type %d", tag_type);

	__near_adapter_remove_target(adapter->idx, target_idx);

	if (adapter->tag_sock == -1)
		return -ENOLINK;

	if (adapter->watch > 0) {
		g_source_remove(adapter->watch);
		adapter->watch = 0;
	}

	g_io_channel_unref(adapter->channel);
	adapter->channel = NULL;
	adapter->tag_sock = -1;
	adapter->tag_link = NULL;

	return 0;
}

int near_adapter_send(uint32_t idx, uint8_t *buf, size_t length,
			near_recv cb, void *data, near_release data_rel)
{
	struct near_adapter *adapter;
	struct near_adapter_ioreq *req = NULL;
	int err;

	DBG("idx %d", idx);

	adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
	if (!adapter) {
		err = -ENODEV;
		goto out_err;
	}

	if (adapter->tag_sock == -1 || !adapter->tag_link) {
		err = -ENOLINK;
		goto out_err;
	}

	if (cb && adapter->watch != 0) {
		req = g_try_malloc0(sizeof(*req));
		if (!req) {
			err = -ENOMEM;
			goto out_err;
		}

		DBG("req %p cb %p data %p", req, cb, data);

		req->target_idx = near_tag_get_target_idx(adapter->tag_link);
		req->cb = cb;
		req->data = data;

		adapter->ioreq_list =
			g_list_append(adapter->ioreq_list, req);
	}

	err = send(adapter->tag_sock, buf, length, 0);
	if (err < 0)
		goto out_err;

	return err;

out_err:
	if (req) {
		GList *last = g_list_last(adapter->ioreq_list);

		g_free(req);
		adapter->ioreq_list =
				g_list_delete_link(adapter->ioreq_list, last);
	}

	if (data_rel)
		return (*data_rel)(err, data);

	return err;
}

static void adapter_listen(gpointer key, gpointer value, gpointer user_data)
{
	struct near_adapter *adapter = value;
	struct near_device_driver *driver = user_data;

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

	if (!adapter->path)
		return;

	driver->listen(adapter->idx, device_read_cb);
}

void __near_adapter_listen(struct near_device_driver *driver)
{
	g_hash_table_foreach(adapter_hash, adapter_listen, driver);
}

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

	connection = near_dbus_get_connection();

	adapter_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
							NULL, free_adapter);

	return 0;
}

void __near_adapter_cleanup(void)
{
	DBG("");

	g_hash_table_destroy(adapter_hash);
	adapter_hash = NULL;
}
