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

#include <stdio.h>

#define CMD_READ_ALL		0x00	/* Read seg 0 (incl: HR) */
#define CMD_READ_SEGS		0x10	/* Read 16 blocks (128 bytes) */
#define CMD_RID			0x78	/* Read tag UID */

#define CMD_WRITE_E		0x53	/* Write with erase */
#define CMD_WRITE_NE		0x1A	/* Write no erase */

#define CMD_WRITE_E8		0x54	/* Write 8 bytes with erase */
#define CMD_WRITE_NE8		0x1B	/* Write 8 bytes no erase */

#define OFFSET_STATUS_CMD	0x00
#define OFFSET_HEADER_ROM	0x01

#define HR0_TYPE1_STATIC_96B	0x11
#define HR0_TYPE1_DYNAMIC_512B	0x12

#define HR0_TYPE2_HIGH		0x10
#define HR0_TYPE2_LOW		0x0F

#define BLOCK_SIZE		8
#define LEN_STATUS_BYTE		0x01	/* Status byte */
#define LEN_SPEC_BYTES		(LEN_STATUS_BYTE + 0x02)	/* HRx */
#define LEN_UID_BYTES		(LEN_STATUS_BYTE + 0x07)	/* UID bytes */
#define LEN_CC_BYTES		0x04	/* Capab. container */
#define LEN_DYN_BYTES		0x0A	/* Bytes CtrlIT and TLV - Dyn. only */

#define TYPE1_MAGIC		0xE1

#define TAG_T1_DATA_UID(data) ((data) + LEN_SPEC_BYTES)
#define TAG_T1_DATA_CC(data) ((data) + LEN_SPEC_BYTES + LEN_UID_BYTES)
#define TAG_T1_DATA_LENGTH(cc) ((cc[2] + 1) * 8 - LEN_CC_BYTES)

#define TAG_T1_DATA_NFC(cc) ((cc)[0] & TYPE1_MAGIC)

#define TYPE1_NOWRITE_ACCESS	0x0F
#define TAG_T1_WRITE_FLAG(cc) ((cc)[3] & TYPE1_NOWRITE_ACCESS)
#define TAG_T1_SEGMENT_SIZE	128

/* Max writable data size */
#define TYPE1_STATIC_MAX_DATA_SIZE_96B		95
#define TYPE1_STATIC_MAX_DATA_SIZE_512B		469

#define UID_LENGTH 4

#define TYPE1_TAG_VER_1_1			0x11
#define TYPE1_TAG_STATIC_SIZE_120			0x0E
#define TYPE1_READ_WRITE_ACCESS			0x00
#define TYPE1_STATIC_TAG_DATA_LENGTH_96B		116
#define TYPE1_STATIC_TAG_DATA_LENGTH_512B		508

#define RESERVED_BLOCK				0x0D
#define FIRST_DYNAMIC_BLOCK			0x02

struct type1_cmd {
	uint8_t cmd;
	uint8_t addr;
	uint8_t data[1];
	uint8_t uid[UID_LENGTH];
} __attribute__((packed));

struct type1_cmd8 {
	uint8_t cmd;
	uint8_t addr;
	uint8_t data[8];
	uint8_t uid[UID_LENGTH];
} __attribute__((packed));

struct type1_cmd_rseg {
	uint8_t cmd;
	uint8_t addr;
	uint8_t data[8];
	uint8_t uid[UID_LENGTH];
} __attribute__((packed));

struct type1_tag {
	uint32_t adapter_idx;
	uint16_t current_block;
	uint16_t current_seg;
	uint16_t last_seg;
	uint16_t data_read;
	uint8_t uid[UID_LENGTH];

	near_tag_io_cb cb;
	struct near_tag *tag;
};

struct t1_cookie {
	uint32_t adapter_idx;
	uint32_t target_idx;
	uint8_t uid[UID_LENGTH];
	uint32_t current_block; /* Static tag */
	uint32_t current_byte;  /* Static tag */
	struct near_ndef_message *ndef;
	near_tag_io_cb cb;
	uint8_t cc[LEN_CC_BYTES];
};

enum type1_tag_version {
	TYPE1_TAG_UNKNOWN,
	TYPE1_TAG_96B,
	TYPE1_TAG_512B
} t1_tag_version;

static void t1_init_cmd(struct type1_tag *tag, struct type1_cmd *cmd)
{
	if (!tag || !cmd)
		return;
	memcpy(cmd->uid, tag->uid, UID_LENGTH);
}

static int t1_cookie_release(int err, void *data)
{
	struct t1_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);
	cookie = NULL;

	return err;
}

/* Read segments (128 bytes) and store them to the tag data block */
static int data_recv(uint8_t *resp, int length, void *data)
{
	struct type1_tag *t1_tag = data;
	struct type1_cmd t1_cmd;
	uint8_t *tagdata;
	size_t data_length;

	DBG("%d", length);

	if (length < 0)
		return length;

	length = length - LEN_STATUS_BYTE;  /* ignore first byte */

	/* Add data to tag mem */
	tagdata = near_tag_get_data(t1_tag->tag, &data_length);

	/* Check that we have enough free space */
	if (data_length - t1_tag->data_read < (uint)length)
		return -EINVAL;

	memcpy(tagdata + t1_tag->data_read, resp + 2, length - LEN_STATUS_BYTE);

	/* Next segment */
	t1_tag->data_read = t1_tag->data_read + length - LEN_STATUS_BYTE;
	t1_tag->current_seg = t1_tag->current_seg + 1;

	if (t1_tag->current_seg <= t1_tag->last_seg) {
		struct type1_cmd_rseg t1_cmd_rseg;

		/* RSEG cmd */
		t1_init_cmd(t1_tag, &t1_cmd);
		t1_cmd_rseg.cmd = CMD_READ_SEGS;
		memset(t1_cmd_rseg.data, 0x00, 8);
		memcpy(t1_cmd_rseg.uid, t1_cmd.uid, sizeof(t1_cmd.uid));
		t1_cmd_rseg.addr = (t1_tag->current_seg << 4) & 0xFF;

		return near_adapter_send(t1_tag->adapter_idx,
				(uint8_t *) &t1_cmd_rseg, sizeof(t1_cmd_rseg),
				data_recv, t1_tag, NULL);
	} else { /* This is the end */
		GList *records;

		DBG("READ complete");

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

		/* free memory */
		g_free(t1_tag);

		return 0;
	}
}

/*
 * The dynamic read function:
 * Bytes [0..3] : CC
 * [4..8]: TLV Lock ControlIT (0x01, 0x03, v1, V2, V3)
 * [9..13]: TLV Reserved Memory Control	(0x02, 0x03, V1, V2, V3)
 * [14..]: TLV NDEF (0x03, L0, L1, L2, V1,V2 ...)
 */
static int read_dynamic_tag(uint8_t *cc, int length, void *data,
				uint8_t tag_mem_size)
{
	struct type1_tag *t1_tag = data;
	struct type1_cmd t1_cmd;
	struct type1_cmd_rseg t1_cmd_rseg;
	uint8_t *tagdata;
	uint8_t	*pndef;
	size_t data_length;

	DBG("Dynamic Mode");
	tagdata = near_tag_get_data(t1_tag->tag, &data_length);

	/* Skip capability container bytes  */
	pndef = cc + 14;		/* right after CC bytes */

	/*
	 * Save first NFC bytes to tag memory
	 * 10 blocks[0x3..0xC] of 8 bytes + 2 bytes from block 2
	 */
	memcpy(tagdata,	pndef, 10 * BLOCK_SIZE + 2);
	t1_tag->data_read = 10 * BLOCK_SIZE + 2;

	/* Read the next one, up to the end of the data area */
	t1_tag->current_seg = 1;
	if (tag_mem_size == HR0_TYPE1_DYNAMIC_512B)
		t1_tag->last_seg = 3;
	else
		return -ENOTSUP;


	/* RSEG cmd */
	t1_init_cmd(t1_tag, &t1_cmd);
	/* T1 read segment */
	t1_cmd_rseg.cmd = CMD_READ_SEGS;
	memset(t1_cmd_rseg.data, 0x00, 8);
	memcpy(t1_cmd_rseg.uid, t1_cmd.uid, sizeof(t1_cmd.uid));
	/* 5.3.3 ADDS operand is [b8..b5] */
	t1_cmd_rseg.addr = (t1_tag->current_seg << 4) & 0xFF;

	return near_adapter_send(t1_tag->adapter_idx,
			(uint8_t *)&t1_cmd_rseg, sizeof(t1_cmd_rseg),
			data_recv, t1_tag, NULL);
}

static int meta_recv(uint8_t *resp, int length, void *data)
{
	struct t1_cookie *cookie = data;
	struct near_tag *tag;
	struct type1_tag *t1_tag;
	uint8_t *cc;
	int err = -EOPNOTSUPP;

	DBG("%d", length);

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

	/* First byte is cmd status */
	if (resp[OFFSET_STATUS_CMD] != 0) {
		DBG("Command failed: 0x%x", resp[OFFSET_STATUS_CMD]);
		err = -EIO;
		goto out_err;
	}

	/* Set tag type */
	if (resp[OFFSET_HEADER_ROM] == HR0_TYPE1_STATIC_96B)
		t1_tag_version = TYPE1_TAG_96B;
	else if (resp[OFFSET_HEADER_ROM] == HR0_TYPE1_DYNAMIC_512B)
		t1_tag_version = TYPE1_TAG_512B;
	else
		t1_tag_version = TYPE1_TAG_UNKNOWN;

	/* Check Magic NFC tag */
	cc = TAG_T1_DATA_CC(resp);
	if (TAG_T1_DATA_NFC(cc) == 0) {
		if (resp[OFFSET_HEADER_ROM] == HR0_TYPE1_STATIC_96B) {
			err = near_tag_add_data(cookie->adapter_idx,
					cookie->target_idx,
					NULL,
					TYPE1_STATIC_TAG_DATA_LENGTH_96B);
		} else if (resp[OFFSET_HEADER_ROM] == HR0_TYPE1_DYNAMIC_512B) {
			err = near_tag_add_data(cookie->adapter_idx,
					cookie->target_idx,
					NULL,
					TYPE1_STATIC_TAG_DATA_LENGTH_512B);
		} else {
			near_error("Not a valid NFC magic tag 0x%x", cc[0]);
			err = -EINVAL;
			goto out_err;
		}
	} else {
		/* Add data to the tag */
		err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx,
						NULL, TAG_T1_DATA_LENGTH(cc));
	}

	if (err < 0)
		goto out_err;

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

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

	t1_tag->adapter_idx = cookie->adapter_idx;
	t1_tag->cb = cookie->cb;
	t1_tag->tag = tag;
	memcpy(t1_tag->uid, cookie->uid, UID_LENGTH);

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

	/* Check Static or Dynamic memory model */
	if (resp[OFFSET_HEADER_ROM] == HR0_TYPE1_STATIC_96B) {
		uint8_t *tagdata;
		size_t data_length;
		GList *records;

		if (TAG_T1_DATA_NFC(cc) == 0)
			near_tag_set_blank(tag, TRUE);
		else
			near_tag_set_blank(tag, FALSE);

		DBG("READ Static complete");

		tagdata = near_tag_get_data(t1_tag->tag, &data_length);

		/* Check that we have enough free space */
		if (data_length < (size_t)TAG_T1_DATA_LENGTH(cc))
			return -EINVAL;

		memcpy(tagdata, cc + LEN_CC_BYTES, TAG_T1_DATA_LENGTH(cc));

		near_tag_set_memory_layout(tag, NEAR_TAG_MEMORY_STATIC);

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

		g_free(t1_tag);

		return 0;
	} else if ((resp[OFFSET_HEADER_ROM] & 0xF0) == HR0_TYPE2_HIGH) {
		near_tag_set_memory_layout(tag, NEAR_TAG_MEMORY_DYNAMIC);
		err = read_dynamic_tag(cc, length, t1_tag,
					resp[OFFSET_HEADER_ROM]);
		/*
		 * As reading isn't complete,
		 * callback shouldn't be called while freeing the cookie
		 */
		cookie->cb = NULL;
	} else {
		err = -EOPNOTSUPP;
	}

	if (err < 0)
		g_free(t1_tag);

out_err:
	DBG("err %d", err);

	return t1_cookie_release(err, cookie);
}

/*
 * READALL to read a maximum of 124 bytes.
 * This cmd is common to static and dynamic targets
 * This should allow to get the HR0 byte.
 */
static int rid_resp(uint8_t *resp, int length, void *data)
{
	struct t1_cookie *cookie = data;
	struct type1_cmd t1_cmd;
	uint8_t *uid;
	int err;

	DBG("");

	/* First byte is cmd status */
	if (resp[OFFSET_STATUS_CMD] != 0) {
		DBG("Command failed: 0x%x", resp[OFFSET_STATUS_CMD]);
		err = -EIO;
		goto out_err;
	}

	uid = TAG_T1_DATA_UID(resp);

	DBG("UID 0x%x 0x%x 0x%x 0x%x", uid[0], uid[1], uid[2], uid[3]);

	near_tag_set_nfcid(cookie->adapter_idx, cookie->target_idx,
							uid, UID_LENGTH);

	t1_cmd.cmd = CMD_READ_ALL;     /* Read ALL cmd give 124 bytes */
	t1_cmd.addr = 0;	       /* NA */
	t1_cmd.data[0] = 0;
	memcpy(t1_cmd.uid, uid, UID_LENGTH);

	memcpy(cookie->uid, uid, UID_LENGTH);

	return near_adapter_send(cookie->adapter_idx,
				(uint8_t *)&t1_cmd, sizeof(t1_cmd),
				meta_recv, cookie, t1_cookie_release);

out_err:
	DBG("err %d", err);

	return t1_cookie_release(err, cookie);
}

static int nfctype1_read_meta(uint32_t adapter_idx, uint32_t target_idx,
						near_tag_io_cb cb, uint8_t *uid)
{
	struct type1_cmd cmd;
	struct t1_cookie *cookie;

	DBG("");

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

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

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

	if (uid) {
		cmd.cmd = CMD_READ_ALL; /* Read ALL cmd give 124 bytes */
		memcpy(cmd.uid, uid, UID_LENGTH);
		memcpy(cookie->uid, uid, UID_LENGTH);

		return near_adapter_send(adapter_idx, (uint8_t *) &cmd,
						sizeof(cmd), meta_recv, cookie,
						t1_cookie_release);
	} else {
		cmd.cmd = CMD_RID;

		return near_adapter_send(adapter_idx, (uint8_t *) &cmd,
						sizeof(cmd), rid_resp, cookie,
						t1_cookie_release);
	}
}

/* First step: RID to get the tag UID */
static int nfctype1_read(uint32_t adapter_idx,
				uint32_t target_idx, near_tag_io_cb cb)
{
	uint8_t *uid;
	uint8_t  uid_length;
	int err;

	DBG("");

	t1_tag_version = TYPE1_TAG_UNKNOWN;
	uid = near_tag_get_nfcid(adapter_idx, target_idx, &uid_length);
	if (!uid || uid_length != UID_LENGTH) {
		if (uid) {
			near_error("Invalid UID");

			g_free(uid);
			return -EINVAL;
		}

		return nfctype1_read_meta(adapter_idx, target_idx, cb, NULL);
	}

	err = nfctype1_read_meta(adapter_idx, target_idx, cb, uid);

	g_free(uid);

	return err;
}

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

	DBG("");

	if (length < 0)
		err = length;

	if (resp[OFFSET_STATUS_CMD] != 0)
		err = -EIO;

	DBG("Done writing");

	return t1_cookie_release(err, cookie);
}

static int write_nmn_e1(struct t1_cookie *cookie)
{
	struct type1_cmd cmd;

	DBG("");

	cmd.cmd = CMD_WRITE_E;
	cmd.addr = 0x08;
	cmd.data[0] = TYPE1_MAGIC;
	memcpy(cmd.uid, cookie->uid, UID_LENGTH);

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

static int data_write_resp(uint8_t *resp, int length, void *data)
{
	struct t1_cookie *cookie = data;
	struct type1_cmd cmd;
	struct type1_cmd8 cmd8;
	uint8_t data_block[BLOCK_SIZE];
	uint8_t addr = 0;
	int err = -EIO;

	DBG("");

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

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

	if (cookie->ndef->offset >= cookie->ndef->length)
		return write_nmn_e1(cookie);

	if (t1_tag_version == TYPE1_TAG_96B) {
		/* Static */
		if (cookie->current_byte >= BLOCK_SIZE) {
			cookie->current_byte = 0;
			cookie->current_block++;
		}

		cmd.cmd = CMD_WRITE_E;
		addr = cookie->current_block << 3;
		cmd.addr = addr | (cookie->current_byte & 0x7);
		cmd.data[0] = cookie->ndef->data[cookie->ndef->offset];
		memcpy(cmd.uid, cookie->uid, UID_LENGTH);
		cookie->ndef->offset++;
		cookie->current_byte++;

		err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
					sizeof(cmd), data_write_resp, cookie,
					NULL);
		if (err < 0)
			goto out_err;

		return err;
	} else {
		/* Dynamic */
		/* Skip reserved and lock/OTP blocks */
		if (cookie->current_block == RESERVED_BLOCK)
			cookie->current_block += 3;

		if ((cookie->ndef->length
			- cookie->ndef->offset) >= BLOCK_SIZE) {
			if (cookie->current_block == FIRST_DYNAMIC_BLOCK) {
				cmd.cmd = CMD_WRITE_E;
				cmd.addr = (FIRST_DYNAMIC_BLOCK << 3)
					| (cookie->current_byte & 0x7);
				cmd.data[0] =
				cookie->ndef->data[cookie->ndef->offset];
				memcpy(cmd.uid, cookie->uid,
					UID_LENGTH);
				cookie->ndef->offset++;
				cookie->current_byte++;
				if (cookie->current_byte >= BLOCK_SIZE)
					cookie->current_block++;
				goto send_byte; /* Write 2 first bytes */
			} else {
				cmd8.cmd = CMD_WRITE_E8;
				cmd8.addr = cookie->current_block;
				memcpy(cmd8.data,
				&cookie->ndef->data[cookie->ndef->offset],
				BLOCK_SIZE);
				cookie->ndef->offset += BLOCK_SIZE;
			}
		} else {
			uint8_t remaining_bytes = 0;

			memset(data_block, 0x00, BLOCK_SIZE);
			cmd8.cmd = CMD_WRITE_E8;
			cmd8.addr = cookie->current_block;
			remaining_bytes = cookie->ndef->length
				- cookie->ndef->offset;
			memcpy(data_block,
				&cookie->ndef->data[cookie->ndef->offset],
				remaining_bytes);
			memcpy(cmd8.data, data_block, BLOCK_SIZE);
			cookie->ndef->offset += remaining_bytes;
		}
		memcpy(cmd8.uid, cookie->uid, UID_LENGTH);
		cookie->current_block++;
		return near_adapter_send(cookie->adapter_idx,
					(uint8_t *)&cmd8,
					sizeof(cmd8), data_write_resp, cookie,
					t1_cookie_release);

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

out_err:
	return t1_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)
{
	int err;
	struct type1_cmd cmd;
	struct t1_cookie *cookie;
	uint8_t *uid, uid_length;

	DBG("");

	uid = near_tag_get_nfcid(adapter_idx, target_idx, &uid_length);
	if (!uid || uid_length != UID_LENGTH) {
		near_error("Invalid type 1 UID");
		err = -EINVAL;
		goto out_err;
	}

	cmd.cmd  = CMD_WRITE_E;
	cmd.data[0] = 0x00;
	memcpy(cmd.uid, uid, UID_LENGTH);

	cookie = g_try_malloc0(sizeof(struct t1_cookie));
	if (!cookie) {
		g_free(uid);
		err = -ENOMEM;
		goto out_err;
	}

	cookie->adapter_idx = adapter_idx;
	cookie->target_idx = target_idx;
	memcpy(cookie->uid, uid, UID_LENGTH);
	cookie->ndef = ndef;
	cookie->cb = cb;
	cmd.addr = 0x08;

	if (t1_tag_version == TYPE1_TAG_96B) {
		/* Static */
		cookie->current_block = 1;
		cookie->current_byte = 4;
	} else {
		/* Dynamic */
		cookie->current_block = 2;
		cookie->current_byte = 6;
	}

	g_free(uid);

	return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
					sizeof(cmd), data_write_resp, cookie,
					t1_cookie_release);
out_err:
	if (cb)
		cb(adapter_idx, target_idx, err);

	return err;
}

/*
 * The writing of a new NDEF message SHALL occur as follows:
 * Write NMN = 00h to indicate that no valid NDEF message is present
 * during writing to allow error detection in the event that the tag
 * is removed from the field prior to completion of operation.
 * Write VNo and RWA if required
 * Write NDEF Message TLV
 * Write NDEF Message data
 * Write NMN = E1h as the last byte to be written
 */
static int nfctype1_write(uint32_t adapter_idx, uint32_t target_idx,
				struct near_ndef_message *ndef,
				near_tag_io_cb cb)
{
	struct near_tag *tag;
	int err;
	size_t t1_size = 0;

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

	/* This check is valid for only static tags.
	 * Max data length on Type 1 Tag including TLV's
	 * is TYPE1_STATIC_MAX_DATA_SIZE */
	if (near_tag_get_memory_layout(tag) == NEAR_TAG_MEMORY_STATIC) {
		if (t1_tag_version == TYPE1_TAG_96B)
			t1_size = TYPE1_STATIC_MAX_DATA_SIZE_96B;
		else
			t1_size = 0;

		if ((ndef->length + 3) > t1_size) {
			near_error("not enough space on tag");
			err = -ENOSPC;
			goto out_err;
		}
	} else if (near_tag_get_memory_layout(tag) ==
			NEAR_TAG_MEMORY_DYNAMIC) {
		if (t1_tag_version == TYPE1_TAG_512B)
			t1_size = TYPE1_STATIC_MAX_DATA_SIZE_512B;
		else
			t1_size = 0;

		if ((ndef->length + 3) > t1_size) {
			near_error("not enough space on tag");
			err = -ENOSPC;
			goto out_err;
		}
	}

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

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

	return err;
}

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

	DBG("%d", length);

	if (length < 0)
		err = -EIO;

	return t1_cookie_release(err, cookie);
}

static int nfctype1_check_presence(uint32_t adapter_idx,
				uint32_t target_idx, near_tag_io_cb cb)
{
	struct type1_cmd t1_cmd;
	struct t1_cookie *cookie;
	uint8_t *uid, uid_length;

	DBG("");

	uid = near_tag_get_nfcid(adapter_idx, target_idx, &uid_length);
	if (!uid || uid_length != UID_LENGTH) {
		near_error("Invalid type 1 UID");
		return -EINVAL;
	}

	t1_cmd.cmd = CMD_READ_ALL;     /* Read ALL cmd give 124 bytes */
	t1_cmd.addr = 0;	       /* NA */
	t1_cmd.data[0] = 0;
	memcpy(t1_cmd.uid, uid, UID_LENGTH);

	g_free(uid);

	cookie = g_try_malloc0(sizeof(struct t1_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 *) &t1_cmd,
				sizeof(t1_cmd), check_presence, cookie,
				t1_cookie_release);
}

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

	DBG("");

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

	if (cookie->current_byte < LEN_CC_BYTES) {
		cmd.cmd  = CMD_WRITE_E;
		addr = cookie->current_block << 3;
		cmd.addr = addr | (cookie->current_byte & 0x7);
		cmd.data[0] = cookie->cc[cookie->current_byte];
		cookie->current_byte++;
		memcpy(cmd.uid, cookie->uid, UID_LENGTH);

		return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
					sizeof(cmd), format_resp, cookie,
					t1_cookie_release);
	} else {
		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 t1_cookie_release(err, cookie);
}

static int nfctype1_format(uint32_t adapter_idx, uint32_t target_idx,
				near_tag_io_cb cb)
{
	int err;
	struct near_tag *tag;
	struct type1_cmd cmd;
	struct t1_cookie *cookie;
	uint8_t *uid, uid_length, addr;

	DBG("");

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

	/* TODO: Dynamic tag format */
	if (near_tag_get_memory_layout(tag) != NEAR_TAG_MEMORY_STATIC)
		return -EOPNOTSUPP;

	uid = near_tag_get_nfcid(adapter_idx, target_idx, &uid_length);
	if (!uid || uid_length != UID_LENGTH) {
		near_error("Invalid type 1 UID");
		return -EINVAL;
	}

	cookie = g_try_malloc0(sizeof(struct t1_cookie));
	if (!cookie) {
		err = -EINVAL;
		goto out_err;
	}

	cookie->adapter_idx = adapter_idx;
	cookie->target_idx = target_idx;
	cookie->cb = cb;
	memcpy(cookie->uid, uid, UID_LENGTH);
	cookie->cc[0] = TYPE1_MAGIC;
	cookie->cc[1] = TYPE1_TAG_VER_1_1;
	cookie->cc[2] = TYPE1_TAG_STATIC_SIZE_120;
	cookie->cc[3] = TYPE1_READ_WRITE_ACCESS;
	cookie->current_block = 1;
	cookie->current_byte = 0;

	cmd.cmd  = CMD_WRITE_E;
	addr = cookie->current_block << 3;
	cmd.addr = addr | (cookie->current_byte & 0x7);
	cmd.data[0] = cookie->cc[cookie->current_byte];
	cookie->current_byte++;
	memcpy(cmd.uid, cookie->uid, UID_LENGTH);
	g_free(uid);

	err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
				sizeof(cmd), format_resp, cookie,
				t1_cookie_release);
	if (err < 0)
		goto out_err;

	return 0;

out_err:
	g_free(cookie);
	g_free(uid);

	return err;
}

static struct near_tag_driver type1_driver = {
	.type           = NFC_PROTO_JEWEL,
	.priority       = NEAR_TAG_PRIORITY_DEFAULT,
	.read           = nfctype1_read,
	.write          = nfctype1_write,
	.check_presence = nfctype1_check_presence,
	.format		= nfctype1_format,
};

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

	return near_tag_driver_register(&type1_driver);
}

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

	near_tag_driver_unregister(&type1_driver);
}

NEAR_PLUGIN_DEFINE(nfctype1, "NFC Forum Type 1 tags support", VERSION,
			NEAR_PLUGIN_PRIORITY_HIGH, nfctype1_init, nfctype1_exit)
