/*
 *
 *  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 <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>

#include <linux/socket.h>

#include <near/nfc_copy.h>
#include <near/plugin.h>
#include <near/log.h>
#include <near/types.h>
#include <near/adapter.h>
#include <near/tag.h>
#include <near/ndef.h>
#include <near/tlv.h>

extern int mifare_read(uint32_t adapter_idx, uint32_t target_idx,
		near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);

extern int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx,
			near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);

extern int mifare_write(uint32_t adapter_idx, uint32_t target_idx,
			struct near_ndef_message *ndef,
			near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);

#define CMD_READ         0x30
#define CMD_READ_SIZE    0x02

#define CMD_WRITE        0xA2

#define READ_SIZE  16
#define BLOCK_SIZE 4

#define META_BLOCK_START 0
#define DATA_BLOCK_START 4
#define TYPE2_MAGIC 0xe1

#define TAG_DATA_CC(data) ((data) + 12)
#define TAG_DATA_LENGTH(cc) ((cc)[2] * 8)
#define TAG_DATA_NFC(cc) ((cc)[0] & TYPE2_MAGIC)

#define TYPE2_NOWRITE_ACCESS	0x0F
#define TYPE2_READWRITE_ACCESS	0x00
#define TAG_T2_WRITE_FLAG(cc) ((cc)[3] & TYPE2_NOWRITE_ACCESS)

#define NDEF_MAX_SIZE	0x30

#define CC_BLOCK_START 3
#define TYPE2_TAG_VER_1_0  0x10
#define TYPE2_DATA_SIZE_48 0x6

struct type2_cmd {
	uint8_t cmd;
	uint8_t block;
	uint8_t data[BLOCK_SIZE];
} __attribute__((packed));

struct type2_tag {
	uint32_t adapter_idx;
	uint16_t current_block;

	near_tag_io_cb cb;
	struct near_tag *tag;
};

struct t2_cookie {
	uint32_t adapter_idx;
	uint32_t target_idx;
	uint8_t current_block;
	struct near_ndef_message *ndef;
	near_tag_io_cb cb;
};

struct type2_cc {
	uint8_t magic;
	uint8_t version;
	uint8_t mem_size;
	uint8_t read_write;
};

static int t2_cookie_release(int err, void *data)
{
	struct t2_cookie *cookie = data;

	DBG("%p", cookie);

	if (!cookie)
		return err;

	if (cookie->cb)
		cookie->cb(cookie->adapter_idx, cookie->target_idx, err);

	if (cookie->ndef)
		g_free(cookie->ndef->data);

	g_free(cookie->ndef);
	g_free(cookie);

	return err;
}

static int data_recv(uint8_t *resp, int length, void *data)
{
	struct type2_tag *tag = data;
	struct type2_cmd cmd;
	uint8_t *nfc_data;
	size_t current_length, length_read, data_length;
	uint32_t adapter_idx;
	int read_blocks;

	DBG("%d", length);

	if (length < 0) {
		g_free(tag);

		return  length;
	}

	nfc_data = near_tag_get_data(tag->tag, &data_length);
	adapter_idx = near_tag_get_adapter_idx(tag->tag);

	length_read = length - NFC_HEADER_SIZE;
	current_length = tag->current_block * BLOCK_SIZE;
	if (current_length + length - NFC_HEADER_SIZE > data_length)
		length_read = data_length - current_length;

	memcpy(nfc_data + current_length, resp + NFC_HEADER_SIZE, length_read);

	if (current_length + length_read == data_length) {
		GList *records;

		/* TODO parse tag->data for NDEFS, and notify target.c */
		tag->current_block = 0;

		DBG("Done reading");

		records = near_tlv_parse(nfc_data, data_length);
		near_tag_add_records(tag->tag, records, tag->cb, 0);

		g_free(tag);

		return 0;
	}

	read_blocks = length / BLOCK_SIZE;
	tag->current_block += read_blocks;

	cmd.cmd = CMD_READ;
	cmd.block = DATA_BLOCK_START + tag->current_block;

	DBG("adapter %d", adapter_idx);

	return near_adapter_send(adapter_idx,
				(uint8_t *) &cmd, CMD_READ_SIZE,
					data_recv, tag, NULL);
}

static int data_read(struct type2_tag *tag)
{
	struct type2_cmd cmd;
	uint32_t adapter_idx;

	DBG("");

	tag->current_block = 0;

	cmd.cmd = CMD_READ;
	cmd.block = DATA_BLOCK_START;

	adapter_idx = near_tag_get_adapter_idx(tag->tag);

	return near_adapter_send(adapter_idx,
					(uint8_t *) &cmd, CMD_READ_SIZE,
					data_recv, tag, NULL);
}

static int meta_recv(uint8_t *resp, int length, void *data)
{
	struct t2_cookie *cookie = data;
	struct near_tag *tag;
	struct type2_tag *t2_tag;
	uint8_t *cc;
	int err;

	DBG("%d", length);

	if (length < 0) {
		err = length;
		goto out_err;
	}

	if (resp[0] != 0) {
		err = -EIO;
		goto out_err;
	}

	cc = TAG_DATA_CC(resp + NFC_HEADER_SIZE);

	/* Default to 48 bytes data size in case of blank tag */
	err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx,
			NULL, (TAG_DATA_LENGTH(cc) ? TAG_DATA_LENGTH(cc) :
			TYPE2_DATA_SIZE_48 << 3));

	if (err < 0)
		goto out_err;

	tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
	if (!tag) {
		err = -ENOMEM;
		goto out_err;
	}

	t2_tag = g_try_malloc0(sizeof(struct type2_tag));
	if (!t2_tag) {
		err = -ENOMEM;
		goto out_err;
	}

	t2_tag->adapter_idx = cookie->adapter_idx;
	t2_tag->cb = cookie->cb;
	t2_tag->tag = tag;

	/* Set the ReadWrite flag */
	if (TAG_T2_WRITE_FLAG(cc) == TYPE2_NOWRITE_ACCESS)
		near_tag_set_ro(tag, TRUE);
	else
		near_tag_set_ro(tag, FALSE);

	near_tag_set_memory_layout(tag, NEAR_TAG_MEMORY_STATIC);

	if (TAG_DATA_NFC(cc) == 0) {
		DBG("Mark as blank tag");
		near_tag_set_blank(tag, TRUE);
	} else {
		near_tag_set_blank(tag, FALSE);
	}

	err = data_read(t2_tag);
	if (err < 0)
		goto out_tag;

	/*
	 * As reading isn't complete,
	 * callback shouldn't be called while freeing the cookie
	 */
	cookie->cb = NULL;
	return t2_cookie_release(err, cookie);

out_tag:
	g_free(t2_tag);

out_err:
	return t2_cookie_release(err, cookie);
}

static int nfctype2_read_meta(uint32_t adapter_idx, uint32_t target_idx,
							near_tag_io_cb cb)
{
	struct type2_cmd cmd;
	struct t2_cookie *cookie;

	DBG("");

	cmd.cmd = CMD_READ;
	cmd.block = META_BLOCK_START;

	cookie = g_try_malloc0(sizeof(struct t2_cookie));
	if (!cookie)
		return -ENOMEM;

	cookie->adapter_idx = adapter_idx;
	cookie->target_idx = target_idx;
	cookie->cb = cb;

	return near_adapter_send(adapter_idx, (uint8_t *) &cmd, CMD_READ_SIZE,
					meta_recv, cookie, t2_cookie_release);
}

static int nfctype2_read(uint32_t adapter_idx,
				uint32_t target_idx, near_tag_io_cb cb)
{
	enum near_tag_sub_type tgt_subtype;

	DBG("");

	tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);

	switch (tgt_subtype) {
	case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
		return nfctype2_read_meta(adapter_idx, target_idx, cb);

	/* Specific Mifare read access */
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
		return mifare_read(adapter_idx, target_idx,
			cb, tgt_subtype);

	default:
		DBG("Unknown Tag Type 2 subtype %d", tgt_subtype);
		return -1;
	}
}

static int data_write_resp(uint8_t *resp, int length, void *data)
{
	int err;
	struct t2_cookie *cookie = data;
	struct type2_cmd cmd;

	DBG("");

	if (length < 0 || resp[0] != 0) {
		err = -EIO;
		goto out_err;
	}

	if (cookie->ndef->offset > cookie->ndef->length) {
		DBG("Done writing");

		return t2_cookie_release(0, cookie);
	}

	cmd.cmd = CMD_WRITE;
	cmd.block = cookie->current_block;
	cookie->current_block++;

	memset(cmd.data,0,BLOCK_SIZE);

	if ((cookie->ndef->offset + BLOCK_SIZE) <
			cookie->ndef->length) {
		memcpy(cmd.data, cookie->ndef->data +
					cookie->ndef->offset, BLOCK_SIZE);
		cookie->ndef->offset += BLOCK_SIZE;
	} else {
		memcpy(cmd.data, cookie->ndef->data + cookie->ndef->offset,
				cookie->ndef->length - cookie->ndef->offset);
		cookie->ndef->offset = cookie->ndef->length + 1;
	}

	return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
					sizeof(cmd), data_write_resp, cookie,
					t2_cookie_release);

out_err:
	return t2_cookie_release(err, cookie);
}

static int data_write(uint32_t adapter_idx, uint32_t target_idx,
				struct near_ndef_message *ndef,
				near_tag_io_cb cb)
{
	struct type2_cmd cmd;
	struct t2_cookie *cookie;
	int err;

	DBG("");

	cookie = g_try_malloc0(sizeof(struct t2_cookie));
	if (!cookie) {
		err = -ENOMEM;
		if (cb)
			cb(adapter_idx, target_idx, err);
		return err;
	}

	cookie->adapter_idx = adapter_idx;
	cookie->target_idx = target_idx;
	cookie->current_block = DATA_BLOCK_START;
	cookie->ndef = ndef;
	cookie->cb = cb;

	cmd.cmd = CMD_WRITE;
	cmd.block = cookie->current_block;
	memcpy(cmd.data, cookie->ndef->data, BLOCK_SIZE);
	cookie->ndef->offset += BLOCK_SIZE;
	cookie->current_block++;

	return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
					sizeof(cmd), data_write_resp, cookie,
					t2_cookie_release);
}

static int nfctype2_write(uint32_t adapter_idx, uint32_t target_idx,
				struct near_ndef_message *ndef,
				near_tag_io_cb cb)
{
	struct near_tag *tag;
	enum near_tag_sub_type tgt_subtype;
	int err;

	DBG("");

	if (!ndef || !cb) {
		err = -EINVAL;
		goto out_err;
	}

	tag = near_tag_get_tag(adapter_idx, target_idx);
	if (!tag) {
		err = -EINVAL;
		goto out_err;
	}

	tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);

	switch (tgt_subtype) {
	case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
		/*
		 * This check is valid for only static tags.
		 * Max data length on Type 2 Tag
		 * including TLV's is NDEF_MAX_SIZE
		 */
		if (near_tag_get_memory_layout(tag) == NEAR_TAG_MEMORY_STATIC) {
			if ((ndef->length) > near_tag_get_data_length(tag)) {
				near_error("Not enough space on tag %zd %zd",
						ndef->length,
						near_tag_get_data_length(tag));
				err = -ENOSPC;
				goto out_err;
			}
		}

		return data_write(adapter_idx, target_idx, ndef, cb);

	/* Specific Mifare write access */
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
		return mifare_write(adapter_idx, target_idx, ndef,
				cb, tgt_subtype);
	default:
		DBG("Unknown TAG Type 2 subtype %d", tgt_subtype);
		err = -EINVAL;
		goto out_err;
	}

	return 0;

out_err:
	if (cb)
		cb(adapter_idx, target_idx, err);

	return err;
}

static int check_presence(uint8_t *resp, int length, void *data)
{
	struct t2_cookie *cookie = data;
	int err = 0;

	DBG("%d", length);

	if (length < 0)
		err = -EIO;

	return t2_cookie_release(err, cookie);
}

static int nfctype2_check_presence(uint32_t adapter_idx, uint32_t target_idx,
							near_tag_io_cb cb)
{
	struct type2_cmd cmd;
	struct t2_cookie *cookie;
	enum near_tag_sub_type tgt_subtype;

	DBG("");

	tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);

	switch (tgt_subtype) {
	case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
		cmd.cmd = CMD_READ;
		cmd.block = META_BLOCK_START;

		cookie = g_try_malloc0(sizeof(struct t2_cookie));
		if (!cookie)
			return -ENOMEM;

		cookie->adapter_idx = adapter_idx;
		cookie->target_idx = target_idx;
		cookie->cb = cb;

		return near_adapter_send(adapter_idx, (uint8_t *) &cmd,
					CMD_READ_SIZE, check_presence, cookie,
					t2_cookie_release);

	/* Specific Mifare check presence */
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
	case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
		return mifare_check_presence(adapter_idx, target_idx,
							cb, tgt_subtype);

	default:
		DBG("Unknown TAG Type 2 subtype %d", tgt_subtype);

		return -1;
	}
}

static int format_resp(uint8_t *resp, int length, void *data)
{
	int err = 0;
	struct t2_cookie *cookie = data;
	struct near_tag *tag;

	DBG("");

	if (length < 0 || resp[0] != 0) {
		err = -EIO;
		goto out_err;
	}

	tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
	if (!tag) {
		err = -EINVAL;
		goto out_err;
	}

	DBG("Done formatting");
	near_tag_set_blank(tag, FALSE);

out_err:
	return t2_cookie_release(err, cookie);
}

static int nfctype2_format(uint32_t adapter_idx, uint32_t target_idx,
				near_tag_io_cb cb)
{
	struct type2_cmd cmd;
	struct t2_cookie *cookie;
	struct near_ndef_message *cc_ndef;
	struct type2_cc *t2_cc;
	struct near_tag *tag;
	enum near_tag_sub_type tgt_subtype;
	int err;

	DBG("");

	tag = near_tag_get_tag(adapter_idx, target_idx);
	if (!tag)
		return -EINVAL;


	tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);

	if (tgt_subtype != NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT) {
		DBG("Unknown Tag Type 2 subtype %d", tgt_subtype);
		return -1;
	}

	t2_cc = g_try_malloc0(sizeof(struct type2_cc));
	cc_ndef = g_try_malloc0(sizeof(struct near_ndef_message));
	cookie = g_try_malloc0(sizeof(struct t2_cookie));

	if (!t2_cc || !cc_ndef || !cookie) {
		err = -ENOMEM;
		goto out_err;
	}

	t2_cc->magic = TYPE2_MAGIC;
	t2_cc->version = TYPE2_TAG_VER_1_0;
	t2_cc->mem_size = TYPE2_DATA_SIZE_48;
	t2_cc->read_write = TYPE2_READWRITE_ACCESS;

	cookie->adapter_idx = adapter_idx;
	cookie->target_idx = target_idx;
	cookie->current_block = CC_BLOCK_START;
	cookie->ndef = cc_ndef;
	cookie->ndef->data = (uint8_t *) t2_cc;
	cookie->cb = cb;

	cmd.cmd = CMD_WRITE;
	cmd.block = CC_BLOCK_START;
	memcpy(cmd.data, (uint8_t *) t2_cc, BLOCK_SIZE);

	err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
				sizeof(cmd), format_resp, cookie, NULL);

out_err:
	if (err < 0) {
		g_free(t2_cc);
		g_free(cc_ndef);
		g_free(cookie);
	}

	return err;
}

static struct near_tag_driver type2_driver = {
	.type           = NFC_PROTO_MIFARE,
	.priority       = NEAR_TAG_PRIORITY_DEFAULT,
	.read           = nfctype2_read,
	.write          = nfctype2_write,
	.check_presence = nfctype2_check_presence,
	.format		= nfctype2_format,
};

static int nfctype2_init(void)
{
	DBG("");

	return near_tag_driver_register(&type2_driver);
}

static void nfctype2_exit(void)
{
	DBG("");

	near_tag_driver_unregister(&type2_driver);
}

NEAR_PLUGIN_DEFINE(nfctype2, "NFC Forum Type 2 tags support", VERSION,
			NEAR_PLUGIN_PRIORITY_HIGH, nfctype2_init, nfctype2_exit)
