/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNfc module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "targetemulator_p.h"

#include <QtCore/QSettings>
#include <QtCore/QDateTime>

#include <QtCore/QDebug>

QT_BEGIN_NAMESPACE

TagBase::TagBase()
:   lastAccess(0)
{
}

TagBase::~TagBase()
{
}

static inline quint8 blockByteToAddress(quint8 block, quint8 byte)
{
    return ((block & 0x0f) << 3) | (byte & 0x07);
}

NfcTagType1::NfcTagType1()
:   hr0(0x11), hr1(0x00), memory(120, '\0')
{
    // Locked blocks
    memory[(0x0e << 3) | 0x00] = 0x01;
    memory[(0x0e << 3) | 0x01] = 0x60;
}

NfcTagType1::~NfcTagType1()
{
}

void NfcTagType1::load(QSettings *settings)
{
    settings->beginGroup(QStringLiteral("TagType1"));

    hr0 = settings->value(QStringLiteral("HR0"), 0x11).toUInt();

    if (!(hr0 & 0x10)) {
        settings->endGroup();
        return;
    }

    hr1 = settings->value(QStringLiteral("HR1"), 0x00).toUInt();

    memory = settings->value(QStringLiteral("Data")).toByteArray();

    //quint8 nmn = memory.at(8);

    quint8 vno = memory.at(9);
    if (vno != 0x10)
        qWarning("Only NFC TagType1 v1.0 behavior is supported.");

    quint8 tms = memory.at(10);
    if (memory.length() != 8 * (tms + 1))
        qWarning("Static memory size does not match TMS value.");

    quint8 rwa = memory.at(11);
    switch (rwa >> 4) {
    case 0:
        // Unrestricted read access tag
        break;
    default:
        // tag with unknown read attributes
        ;
    }

    switch (rwa & 0x0f) {
    case 0:
        // Unrestricted write access tag
        break;
    case 0x0f:
        // Read only tag
        break;
    default:
        // tag with unknown write attributes
        ;
    }

    //quint16 lock = (quint8(memory[blockByteToAddress(0x0e, 1)]) << 8) |
    //               quint8(memory[blockByteToAddress(0x0e, 0)]);

    settings->endGroup();
}

QByteArray NfcTagType1::uid() const
{
    lastAccess = QDateTime::currentMSecsSinceEpoch();

    return memory.left(7);
}

quint8 NfcTagType1::readData(quint8 block, quint8 byte)
{
    return memory.at((block << 3) | byte);
}

QByteArray NfcTagType1::processCommand(const QByteArray &command)
{
    lastAccess = QDateTime::currentMSecsSinceEpoch();

    QByteArray response;

    bool tagType1 = (hr0 & 0xf0) == 0x10;
    bool dynamic = (hr0 & 0x0f) != 0x01;

    if (command.length() == 9) {
        // static memory model command
        quint8 opcode = command.at(0);
        quint8 address = command.at(1);
        quint8 data = command.at(2);
        QByteArray uid = command.mid(3, 4);

        // check checksum
        if (qChecksum(command.constData(), command.length(), Qt::ChecksumItuV41) != 0)
            return QByteArray();

        // check UID
        if (uid != memory.left(4))
            return QByteArray();

        switch (opcode) {
        case 0x00:  // RALL
            response.append(hr0);
            response.append(hr1);
            response.append(memory.left(120));
            break;
        case 0x01:  // READ
            response.append(address);
            if (address & 0x80)
                response.append(char(0x00));
            else
                response.append(memory.at(address));
            break;
        case 0x53: { // WRITE-E
            quint8 block = address >> 3;
            if (block == 0x00 || block == 0x0d || block == 0x0e)    // locked blocks
                break;

            quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
            if ((0x01 << block) & lock)    // locked blocks
                break;

            // FIXME: Test dynamic lock bytes

            memory[address] = data;

            response.append(address);
            response.append(data);
            break;
        }
        case 0x1a: { // WRITE-NE
            quint8 block = address >> 3;
            if (block == 0x00 || block == 0x0d)  // locked blocks
                break;

            quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
            if ((0x01 << block) & lock)    // locked blocks
                break;


            // FIXME: Test dynamic lock bytes

            memory[address] = memory.at(address) | data;

            response.append(address);
            response.append(memory.at(address));
            break;
        }
        case 0x78:  // RID
            response.append(hr0);
            response.append(hr1);
            response.append(memory.left(4));
            break;
        }
    } else if (tagType1 && dynamic && command.length() == 16) {
        // dynamic memory model command
        quint8 opcode = command.at(0);
        quint8 address = command.at(1);
        QByteArray data = command.mid(2, 8);
        QByteArray uid = command.mid(10, 4);

        // check checksum
        if (qChecksum(command.constData(), command.length(), Qt::ChecksumItuV41) != 0)
            return QByteArray();

        // check UID
        if (uid != memory.left(4))
            return QByteArray();

        switch (opcode) {
        case 0x10: // RSEG
            response.append(address);
            response.append(memory.mid(128 * (address >> 4), 128));
            break;
        case 0x02:  // READ8
            response.append(address);
            response.append(memory.mid(8 * address, 8));
            break;
        case 0x54: { // WRITE-E8
            // locked blocks
            if (address == 0x00 || address == 0x0d || address == 0x0e || address == 0x0f)
                break;

            quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
            if (address <= 0x0e && ((0x01 << address) & lock))  // locked blocks
                break;

            // FIXME: Test dynamic lock bytes

            memory.replace(address * 8, 8, data);

            response.append(address);
            response.append(memory.mid(address * 8, 8));
            break;
        }
        case 0x1b:  // WRITE-NE8
            // locked blocks
            if (address == 0x00 || address == 0x0d || address == 0x0e || address == 0x0f)
                break;

            quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
            if (address <= 0x0e && ((0x01 << address) & lock))  // locked blocks
                break;

            // FIXME: Test dynamic lock bytes

            for (int i = 0; i < 8; ++i)
                memory[address * 8 + i] = memory.at(address * 8 + i) | data.at(i);

            response.append(address);
            response.append(memory.mid(address * 8, 8));
            break;
        }
    }

    if (!response.isEmpty()) {
        quint16 crc = qChecksum(response.constData(), response.length(), Qt::ChecksumItuV41);
        response.append(quint8(crc & 0xff));
        response.append(quint8(crc >> 8));
    }

    return response;
}


NfcTagType2::NfcTagType2()
:   memory(64, 0x00), currentSector(0), expectPacket2(false)
{
}

NfcTagType2::~NfcTagType2()
{
}

void NfcTagType2::load(QSettings *settings)
{
    settings->beginGroup(QStringLiteral("TagType2"));

    memory = settings->value(QStringLiteral("Data")).toByteArray();

    settings->endGroup();
}

QByteArray NfcTagType2::uid() const
{
    lastAccess = QDateTime::currentMSecsSinceEpoch();

    return memory.left(3) + memory.mid(4, 4);
}

#define NACK QByteArray("\x05")
#define ACK QByteArray("\x0a")

QByteArray NfcTagType2::processCommand(const QByteArray &command)
{
    lastAccess = QDateTime::currentMSecsSinceEpoch();

    QByteArray response;

    // check checksum
    if (qChecksum(command.constData(), command.length(), Qt::ChecksumItuV41) != 0)
        return QByteArray();

    if (expectPacket2) {
        expectPacket2 = false;
        quint8 sector = command.at(0);
        if (sector * 1024 > memory.length())
            return NACK;
        else {
            currentSector = sector;
            return QByteArray();
        }
    }

    quint8 opcode = command.at(0);

    switch (opcode) {
    case 0x30: {    // READ BLOCK
        quint8 block = command.at(1);
        int absoluteBlock = currentSector * 256 + block;

        response.append(memory.mid(absoluteBlock * 4, 16));
        if (response.length() != 16)
            response.append(QByteArray(16 - response.length(), '\0'));

        break;
    }
    case 0xa2: {    // WRITE BLOCK
        quint8 block = command.at(1);
        int absoluteBlock = currentSector * 256 + block;

        // locked blocks
        if (absoluteBlock == 0 || absoluteBlock == 1)
            return NACK;

        const QByteArray data = command.mid(2, 4);

        memory.replace(absoluteBlock * 4, 4, data);

        return ACK;
    }
    case 0xc2:  // SECTOR SELECT - Packet 1
        if (memory.length() > 1024) {
            expectPacket2 = true;
            return ACK;
        }

        return NACK;
    default:
        qDebug() << "Unknown opcode for Tag Type 2" << hex << opcode;
        qDebug() << "command:" << command.toHex();

        return NACK;
        ;
    }

    if (!response.isEmpty()) {
        quint16 crc = qChecksum(response.constData(), response.length(), Qt::ChecksumItuV41);
        response.append(quint8(crc & 0xff));
        response.append(quint8(crc >> 8));
    }

    return response;
}

QT_END_NAMESPACE
