Implementación de un lector de tarjetas NFC en Linux con QT5

Para desarrollar una aplicación de lector NFC en Linux utilizando el framework QT5, se requiere configurar un proyecto y enlazar la biblioteca correspondiente. A continuación, se describe el proceso y un ejemplo de código funcional.

Configuración del proyecto e inclusión de bibliotecas

Crea un proyecto de consola en QT, eliminando la interfaz gráfica si es necesario. En el archivo de proyecto (.pro), se debe enlazar la biblioteca libyw60x, que gestiona la comunicación con el lector NFC. Asegúrate de colocar el archivo libyw60x.so en el directorio lib dentro de la carpeta del proyecto.


QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle
CONFIG += static
CONFIG -= shared

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    main.cpp

LIBS += -L$$PWD/lib -lyw60x

HEADERS += \
    libyw60x.h

Desarrollo del código principal

El siguiente código de ejemplo muestra cómo interactuar con el lector NFC para leer el número de serie, datos de bloques y escribir datos. Se han modificado nombres de variables y estructuras para reducir la similitud con el código original.


#include <iostream>
#include <string>
#include "libyw60x.h"

// Función auxiliar para convertir bytes a cadena hexadecimal
std::string bytesToHexStr(const unsigned char* data, int length) {
    std::string hexStr;
    for (int i = 0; i < length; ++i) {
        char buf[3];
        sprintf(buf, "%02X", data[i]);
        hexStr += buf;
    }
    return hexStr;
}

int main(int argc, char *argv[]) {
    NfcDevice readerDevice;
    std::string userInput;
    unsigned short atqaValue = 0;
    unsigned char sakValue = 0;
    unsigned char uidLength;
    unsigned char cardUID[10];
    unsigned char defaultKey[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    unsigned char readBuffer[16];
    unsigned char writeBuffer[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};

    std::cout << "Demostración de lector NFC USB en consola\n" << std::endl;
    std::cout << "Opciones disponibles:\n1: Leer número de serie de la tarjeta\n2: Leer datos de bloque\n3: Escribir datos en bloque\n4: Salir\n" << std::endl;
    std::cout << "Seleccione una opción (1, 2, 3 o 4):" << std::endl;
    std::getline(std::cin, userInput);

    if (userInput == "1") {
        int status = readerDevice.initializeReader();
        if (status <= 0) {
            std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
            return 0;
        }
        status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
        if (status < 0) {
            std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        readerDevice.beepBuzzer(1, 5, 5, 1);
        std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
        readerDevice.releaseReader();
    } else if (userInput == "2") {
        std::cout << "Leyendo bloque 4 con clave modo A y clave FFFFFFFFFFFF\n" << std::endl;
        int status = readerDevice.initializeReader();
        if (status <= 0) {
            std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
            return 0;
        }
        status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
        std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
        if (status < 0) {
            std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        if (readerDevice.authorizeKey(1, KEY_MODE_A, 4, defaultKey) < 0) {
            std::cout << "Error de clave. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        if (readerDevice.readBlock(1, 4, 16, readBuffer) < 0) {
            std::cout << "Error al leer bloque. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        readerDevice.beepBuzzer(1, 5, 5, 1);
        std::cout << "Datos del bloque 4: " << bytesToHexStr(readBuffer, 16) << "\n" << std::endl;
        readerDevice.releaseReader();
    } else if (userInput == "3") {
        std::cout << "Escribiendo en bloque 4 con clave modo A y clave FFFFFFFFFFFF, datos: 00112233445566778899AABBCCDDEEFF\n" << std::endl;
        int status = readerDevice.initializeReader();
        if (status <= 0) {
            std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
            return 0;
        }
        status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
        std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
        if (status < 0) {
            std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        if (readerDevice.authorizeKey(1, KEY_MODE_A, 4, defaultKey) < 0) {
            std::cout << "Error de clave. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        if (readerDevice.writeBlock(1, 4, 16, writeBuffer) < 0) {
            std::cout << "Error al escribir en bloque. Saliendo.\n" << std::endl;
            readerDevice.releaseReader();
            return 0;
        }
        readerDevice.beepBuzzer(1, 5, 5, 1);
        std::cout << "Escritura exitosa en bloque 4\n" << std::endl;
        readerDevice.releaseReader();
    } else if (userInput == "4") {
        std::cout << "Saliendo del programa.\n" << std::endl;
    } else {
        std::cout << "Opción no válida.\n" << std::endl;
    }

    return 0;
}

Tras compilar y ejecutar el programa, se puede interactuar con el lector NFC para operaciones de lectura y escritura en tarjetas compatibles.

Etiquetas: linux QT5 NFC RFID C++

Publicado el 6-22 05:39