/*
 * QrfeGen2Tag.cpp
 *
 *  Created on: 30.07.2009
 *      Author: stefan.detter
 */

#include "../inc/tag/QrfeGen2Tag.h"
#include "../inc/epc/EPC_Defines.h"

#include "../inc/tagId/QrfeGS1TagIdFactory.h"

//EPC Wordpointer Addresses
/** Definition for EPC wordpointer: Address for CRC value */
#define MEMADR_CRC        0x00
/** Definition for EPC wordpointer: Address for PC value Word position*/
#define MEMADR_PC         0x01
/** Definition for EPC wordpointer: Address for EPC value */
#define MEMADR_EPC        0x02


/** Definition for EPC wordpointer: Address for kill password value */
#define MEMADR_KILLPWD    0x00
/** Definition for EPC wordpointer: Address for access password value */
#define MEMADR_ACCESSPWD  0x02

/** Definition for EPC wordpointer: Address for TID value */
#define MEMADR_TID        0x00


QrfeGen2Tag::QrfeGen2Tag(QString tagId, QrfeGen2ManipulatorInterface* reader, QObject* parent)
	: QrfeTagInterface(tagId, reader, parent)
	, m_gen2reader(reader)
{

}

QrfeGen2Tag::~QrfeGen2Tag()
{
}

QrfeGlobal::TMIResult QrfeGen2Tag::readInformations()
{
	QByteArray tid;

	QrfeGlobal::TMIResult res = QrfeGlobal::TMI_ERROR;

    res = m_reader->readFromTag(m_tagId, MEM_TID, 0, QByteArray(4, (char)0), 4, tid);
	if(res != QrfeGlobal::TMI_OK)
		return res;

    int size = EPCGlobal::getTIDInfoSize(tid);

    if(size != tid.size())
    {
        QByteArray addition;
        res = m_reader->readFromTag(m_tagId, MEM_TID, 4, QByteArray(4, (char)0), size-tid.size(), addition);
        if(res != QrfeGlobal::TMI_OK)
            return res;

        tid.append(addition);
    }

	emit stepDone(1, 2);

	EPCGlobal::TID_Info info = EPCGlobal::getTIDInfo(tid);

	m_manufacturer 		= info.manufacturer;
	m_model 			= info.model;
	m_userMemSize 		= info.userMemSize;
	m_hasSerialNumber	= info.hasSerialNumber;
	m_serialNumber		= info.serialNumber;

	emit stepDone(2, 2);


	return QrfeGlobal::TMI_OK;
}

QrfeGen2ManipulatorInterface* QrfeGen2Tag::tagManipulatorInterface()
{
	return m_gen2reader;
}



QrfeGlobal::TMIResult QrfeGen2Tag::setTagId ( QString tagId_After, QByteArray passwd )
{
	bool ok = false;
	bool sizeDiff = false;

	QByteArray epc_after = QrfeGlobal::stringToBytes(tagId_After, &ok);
	if(!ok)	return QrfeGlobal::TMI_ERROR;

	if(epc_after.size()%2 != 0)
		return QrfeGlobal::TMI_ERROR;

	QrfeGlobal::TMIResult res = writeToTag(MEM_EPC, MEMADR_EPC, passwd, epc_after);
	if(res != QrfeGlobal::TMI_OK)
		return res;

	if(tagId_After.size() != m_tagId.size())
		sizeDiff = true;

	m_tagId = QrfeGlobal::bytesToString(epc_after.left(this->tagIdBytes().size()));

	if(sizeDiff)
	{
		uchar wordCount = epc_after.size()/2;

		QByteArray pc;

		res = readFromTag(MEM_EPC, MEMADR_PC, passwd, 2, pc);
		if(res != QrfeGlobal::TMI_OK)
			return res;

		uchar t = pc[0];
		t &= 0x07;
		t |= ((wordCount) << 3);
		pc[0] = t;

		res = writeToTag(MEM_EPC, MEMADR_PC, passwd, pc);
		if(res != QrfeGlobal::TMI_OK)
			return res;
	}

	if(res == QrfeGlobal::TMI_OK)
		m_tagId = tagId_After;

	return res;
}

QrfeGlobal::TMIResult QrfeGen2Tag::setAccessPassword ( QByteArray currentPassw, QByteArray newPassw )
{
	return m_reader->writeToTag(m_tagId, QrfeGen2Tag::MEM_RES, MEMADR_ACCESSPWD, currentPassw, newPassw);
}

QrfeGlobal::TMIResult QrfeGen2Tag::setKillPassword ( QByteArray currentPassw, QByteArray newPassw )
{
	return m_reader->writeToTag(m_tagId, QrfeGen2Tag::MEM_RES, MEMADR_KILLPWD, currentPassw, newPassw);
}




QrfeGlobal::TMIResult QrfeGen2Tag::readFromTag ( MEMORY_BANK mem_bank, ushort address, QByteArray passwd, uchar count, QByteArray &data )
{
	return m_reader->readFromTag(m_tagId, mem_bank, address, passwd, count, data);
}

QrfeGlobal::TMIResult QrfeGen2Tag::writeToTag ( MEMORY_BANK mem_bank, ushort address, QByteArray passwd, QByteArray data, bool retry )
{
	return m_reader->writeToTag(m_tagId, mem_bank, address, passwd, data);
}


QrfeGlobal::TMIResult QrfeGen2Tag::lockTag ( LOCK_MODE mode, LOCK_MEMORY_SPACE memory, QByteArray passwd )
{
	return m_gen2reader->lockTag(m_tagId, mode, memory, passwd);
}

QrfeGlobal::TMIResult QrfeGen2Tag::killTag ( QByteArray killPassword )
{
	return m_gen2reader->killTag(m_tagId, killPassword);
}





QrfeGen2ManipulatorInterface* QrfeGen2Tag::gen2TagManipulatorInterface()
{
	return m_gen2reader;
}
